Send captured image to socket server

Well, your problem was more likely receiving the chunks in the incorrect order than the data in the chunk itself being corrupted. Breaking the data out into more well defined chunks with some additional meta data to rebuild them in the proper order could help with that. Including a CRC would help you to validate the data sent is the data received.

The other possibility would be either trying to put too much data on the send buffer too quickly or not reading it off of the other end fast enough but it looks like you already tried to slow it down.

If you can’t send 5 bytes without the data being corrupted you might have bigger problems and I’m not sure a web service will help unless maybe you were using a UDP connection before. I would definitely recommend using a TCP socket for a project like this.

That’s what i am trying to do…

Uh ? Sorry Alex … And how you talk to wifly?? I don’t get your hw setup… :open_mouth:

I talk to wifly using a c# program based on windows socket… (my PC and robot are connected to wifi router without wires) Do you mean that socket connection use a serial port under the hood? Or i don’t understand something?

Can you show better your setup ? I can imagine that robot has netmf device with wifly attached and a PC rceives data from robot via wifi connection. Are you using ad-hoc connection to wifly or an AP ?
If you have attached WiFly to Cerberus/Cebuino for sure the phisical connection is using serial rs232 protocol, then driver abstracts your C# program.

I don’t use Ad-hoc or AP. I am using home wifi router…
My steps are:

  1. Start listening on port 1988 in C# program (my PC)
  2. Turn on the robot power-> wifly module joins home network->WiFlySocket connects to PC EndPoint.
  3. From PC i send a command to capture image to robot and wait for bytes response…
    that’s all my steps… not too much as you can see))

Guys can you help me please to find out how to use Sockets with RoShmi’s driver? I am going to try using it instead of toolbox WiFlyGSX driver… and WiFlySocket.

My socket server and socket client connection worked well when i used WIFlyGSX. I could connect to socket server and send/recieve data:


WiFlyGSX _wifi = new WiFlyGSX("COM1",230400,"$");
_wifi.EnableStaticIP("192.168.0.62", "255.255.255.0", "192.168.0.1", "192.168.0.1");
_wifi.JoinNetwork("BilityukA", 0, WiFlyGSX.AuthMode.WPA2_PSK, "New999manAlex");  
WiFlySocket _socket = new WiFlySocket("192.168.0.43", 1988,_wifi);
_socket.Connect();

I cannot setup RoShmi’s driver to send/recieve data using sockets. Instead of WiFlySocket i am trying to use System.Net.Socket with your wifi_RN171 interface because WiFlySocket doesnt have an option to use your interface, it needs WiFlyGSX interface.
Here is a code where the method _socket.Connect() doesn’t work as expected;


WiFi_RN171 wifi_RN171 = new WiFi_RN171(Reset, Reset, 230400, System.IO.Ports.Parity.None, WiFi_RN171.DebugMode.StandardDebug);
wifi_RN171.SetDebugLevel(WiFi_RN171.DebugLevel.DebugAll);
wifi_RN171.EnableStaticIP("192.168.0.62", "192.168.0.1", "255.255.255.0", "192.168.0.1");
bool ActionResult = wifi_RN171.JoinWirelessNetwork("BilityukA", "New999manAlex", 0, Gadgeteer.Modules.RoSchmi.WiFi_RN171.WirelessEncryptionMode.WPA2_PSK);
System.Net.Socket  _socket = new System.Net.Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPHostEntry hostEntry = Dns.GetHostEntry("192.168.0.43");
                _socket.Connect(new IPEndPoint(hostEntry.AddressList[0],1988));//HERE IT DOESNT WORK. JUST HOLDS WITHOUT ANY EXCEPTION

Also EnableStaticIP in RoSchmi’s driver doesn’t work for me as expected. You can see that i set up static IP as 192.168.0.62, but every time wifi_RN171.LocalIP returns 192.168.0.67
Maybe Roschmi can help ;D

Thanks Alex, now it is clear for me.

I think you are making a bit of confusion. The Roschmi driver doesn’t support socket for what I see taking a fast look into it. The WiFly doesn’t need any socket to send data, but you need on receiving program (if not using an other wifly).
All the show is managed setting protocol/port (TCP in this case, look into the driver code) and the baudrate. Then you OPEN the connection to a listening socket port on the PC.
Everything you send from now on to the netmf serial port DIRECTLY is presented on the peer socket (PC) until you CLOSE the connection.
I hope to have cleared the point.
You can create a socket-like software class as it is done in toolbox driver, but IT IS NOT compatible with Microsoft.NET.Socket !

Thank you very much for reply dobova, sorry but i dont really understand how the wifi_RN171 know the remote server ip address? I mean if it doesnt need a socket for connection and i run a socket listener on my PC on port 1988 and ip address of my PC is 192.168.0.43 how do i use wifi_RN171.Send()??? wifi_RN171 doesn’t know that it need to send data to 192.168.0.43 ip address… Also i dont understand how to recieve data on wifly side if it’s not using a socket??? Where is recieve method???

@ Alex Bilityuk - I’d expect a connect() method that set remote address/port and issues a “open” command to the wifly … but I think that Roshmi can help you better how-to use the driver.

The flow on netmf is:

  • InitWifly (baudrate, COM name, flow control)
  • Set local parameters (IP addr, Gateway, port)
  • Set remote parameters (IP addr, port)
  • Set wifly in “OPEN” mode (it connect to remote socket in this case on port specified, firing accept() on PC)
  • Send/receive data using Send() or receive through the OnReceiveData() (event fired by the driver [may be similar name]).
  • Set wifly in “CLOSE” mode (socket on peer will report endconnection)

That’s all folk.

1 Like

Your are right man That’s all folk. ;D
Ok, question is opened… waiting forward for Roshmi’s help…

Sorry, I’m still on vacation. I’ l be back home this weekend to have a look on file transfer over RN171

1 Like

Ok RoSchimi… have a nice vacation!!!

@ Alex Bilityuk - I’m interested Roshmi driver too.
I’m looking little bit inside it and I see that instead of base sockets, Roshmi has implemented HttpWebRequest/Response classes. That is interesting.
The “server” side in this case will become a client, calling from full .NET WebRequest classes the webserver on Cerb and getting back image data.
My description isn’t much clear if you are not familiar with WebRequest protocol, but in the weekend I will try some code.
Just to give an example, using a normal browser, you can call the Webserver on the cerb and get response image, directly displaying it. No code on PC to debug.

::slight_smile:

1 Like

@ dobova -
It would be great to take a look on WebRequest code sample!!!

During the week and a half of struggling with my problem i finally could send a pictured image to PC using a RoSchmi’s driver. I rewrite my code a little, instead of implementing a socket server on PC i started listening a port on cerbuino side (as you suggested) and made a PC as a client. And finally i did it ;D When i completly done with a project post some video for sure!!! I was able to reach 40 seconds delay during image transmission (512 bytes per chunk with 100 msec thread sleep on each iteration)
Now i have some questions about RoSchmi’s driver implementation…
I still can’t set a static ip to the module and listening port is not changed too…
For examle i set:


WifiRN171.SetStaticIP(192.168.0.62,192.168.0.1,255.255.255.0,192.168.0.1);
WifiRN171.SetLicteningPort(1988);

But in debug output i can see that dhcp is still on and it set ip as 192.168.0.67 also port is set to 2000 and this causes some problem when sending/recieving data between server and client… When i read the data in client side the chunks comes with HELLO and when i process the data on server side in DataRecieved event it comes with additional information like OPEN CLOSE. I think that is because of the 2000 port. This port is reserved for telnet commands.

Waiting forward your results with a web implementation! Really interesting how much time does it take to show up a picture in browser))
Thank you for advices!!!

Hi Alex, hi dobova,
As already mentioned most code of the driver is not my work but is the GHI driver of the discontinued RN171 Module. So I do not know everthing about the features of the driver which was apparently not ready in all its aspects

For me setting a static IP works, here is an example for the IP-address 192.168.1.57
bool ActionResult = wifi_RN171.JoinWirelessNetwork(“mySSID”, “myPassword”, 0, WiFi_RN171.WirelessEncryptionMode.WPA2_PSK, false, “192.168.1.57”, “192.168.1.1”, “255.255.255.0”, “192.168.1.1”);

The listening port can be set with the command
wifi_RN171._Command_Execute(“set ip localport 80”);

to avoid the „Hello" meassage when connected to a client use the command
wifi_RN171._Command_Execute(“set comm remote 0”);

to avoid the OPEN and CLOS messages tot he serial port use the commands
wifi_RN171._Command_Execute(“set comm open 0”);
wifi_RN171._Command_Execute(“set comm close 0”);

@ RoSchmi - I’ve started a test project based on your code using Cerberus 4.3.5 and RN-XV module (on gadgeteer module on socket 2)



        void ProgramStarted()
        {

            wifi_RN171 = new WiFi_RN171(2, 115200);
            wifi_RN171.SetDebugLevel(WiFi_RN171.DebugLevel.DebugAll);


            wifi_RN171.EnableDHCP("192.168.20.1", "255.255.255.0", "192.168.20.1");


            bool ActionResult = wifi_RN171.JoinWirelessNetwork("MYSSID", "MYPASSWD", 0, Gadgeteer.Modules.RoSchmi.WiFi_RN171.WirelessEncryptionMode.WPA2_PSK);

            wifi_RN171.HttpRequestReceived += wifi_RN171_HttpRequestReceived;

            executeCommand(0);
            executeCommand(2); // disable HELLO string from XV
            executeCommand(1);

            if (wifi_RN171.EnableHttpServer())
                Debug.Print("Ok ::: WebServer Started!"); //Enable HTTP Parsing

            // Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
            Debug.Print("Program Started");
        }

// as per your example code:
        void wifi_RN171_HttpRequestReceived(HttpStream request)
        {
            Debug.Print("HttpRequest");

            string requestedURL = request.Request.URL;
            Debug.Print("Selected URL = " + requestedURL);
            if (requestedURL == "/index.html")
            {
                request.Response.HeaderData["Content-type"] = "text/html";
                request.Response.HeaderData["Connection"] = "close";
                request.Response.HeaderData["Cache-Control"] = "no-cache";
                request.Response.StatusCode = GTM.GHIElectronics.HttpResponse.ResponseStatus.OK;

                byte[] document = System.Text.Encoding.UTF8.GetBytes("<html><head></head><body>HELLO world littlething</body></html>");

                request.Response.HeaderData["Content-Length"] = document.Length.ToString();

                //All you have to do is send the document data through the response object.
                //Header data is automatically applied for you when you chose to send.

                request.Response.Send(document);

                Debug.Print("Response sent -> length: " + document.Length.ToString());
            }
            else
            {
                // Debug.Print("Hello not connected");
            }
        }



The code “mostly” work in DHCP mode. I’ve not tested with fixed IP. It’s important to send “set comm remote 0” otherwise the HTTP format of the response will be corrupted.
The problem I face is that localport is always 2000 and not 80 as cmd are setting. The XV aknowledge the port change but in the browser (firefox) I still need to use
http://192.168.20.x:2000/index.html" to access module and not on port 80. :open_mouth:

Until now I didn’t realize the reason of this problem.

@ dobova -
Hi,
I only made preliminary tests with this driver.
I only tried the http server function in AP-Mode, which was the example that GHI showed for the RN171 Gadgeteer Module.
When AP-Mode is used (the RN171 acts as DHCP Server, function can be selected by #define directives in my example) the listening port is set to 80.
Perhaps it is better to set it to 80 in JoinNetwork Mode too.
I simply set it to 2000 in the JoinWirelessNetwork method as it is set by default in the RN171 firmware without thinking much about this. You can set it to 80 in the driver or perhaps later.
Sometimes it is necessary to do a “save” and “reboot” command to reach that the RN171 takes it over.
Do you think, I should better change this to 80 in a next version?

@ RoSchmi - Probably to change the port, the module needs a reboot or similar command. I will take a look through the RN171 docs.
On my opinion it is important to be able to change listen port, but I don’t think it is important as default port to set 80. When you start httpserver than is good idea to default it at 80.

EDIT:

:wall:
Damned module! It retain listen port until a reboot. I couldn’t change it dinamically. It is not enough to “leave” and “join” again!
So you need a preconfigure stage, save and reboot. Then join again…