Connect photon to different station in Wifi Network over Router without Internet?

Hello Team Photon,

Greetings…!

I have two photon devices. I want to connect both these photons to a Laptop in the Network around one WiFi Router.

Photon1 <------> Router <-------> Laptop
|
Photon2 <----------|

I want to transmit data from both these photons to Laptop and receive back from Laptop. I will increase number of photons in the network based on the Throughput of the network.

I am looking for this network around WiFi router without Internet so that I can use this network anywhere.

Please suggest me needful. Please provide the info of already available such thread.

Thanks.!
Kind Regards,
Iqram

You could have a look at the TCPClient/TCPClient objects in the docs or even UDP.
We could point you there, but you will find these threads by using the search feature too.

1 Like

Thanks you ScruffR…!! I will have a look and try it on my Photon.

I will come back here in case I will stuck (I will be, I know ;)).

Kind Regards,
Iqram

@ScruffR Thanks for your useful comment. I got the code from other similar threads and could use the TCPClient documentation of particle.io. I am able to do Data transmission on TCP/UDP from photon client to Laptop as a server.

I am using netcat to read received data on laptop. I am transmitting 4KB of data from Photon, but netcat is give lesser data then transmitted from photon. It gives remaining data in the next reception and again blocks data of new chunk received. I am thinking that Photon is doing its job nicely. How to deal with it?

Please suggest me needful.

Thanks.!
Kind Regards,
Iqram

Could you show what you have carried together in your current code then?
@rickkas7 is the guy to ask when it comes to TCP/UDP questions. He’s done some extensive testing and I guess you’ve come across some of his very useful code samples.

Using TCP there is no guarantee that the receiver will get the same amount of data you transmit at once - it will almost certainly be split into varying sized pieces that arrive in order, but over a period of time.

However, you are probably encountering a different problem: It works best if you don’t write more than 1024 bytes at a time using the write() method of the TCPClient (or the TCPClient returned by TCPServer). You can still send 4096 bytes, you just do it in 4 chunks of 1024 bytes each. Furthermore, if the write method on the Photon returns a value of -16, you must later (either after returning from loop and getting called again or after a delay()) write the exact same data again. This result code means the internal buffers were full and that data was not buffered for sending. If you don’t write the same data again, some of your data will be missing when the receiver gets it.

2 Likes

@ScruffR @rickkas7 Thanks for your suggestions…!!

Please find my code below for TCP transmission from Photon as a client. There was a mistake in previous data points. I apologize for that. The correction is, data size is 8KB and Netcat stops printing data after 0x160f bytes.

#define NO_OF_BYTES 8192

unsigned char TxMsg[NO_OF_BYTES];
unsigned int i, msgWriteLength = 0;

byte server[] = { 192, 168, 0, 103 };

TCPClient client;

void setup() {
    Serial.begin(9600);
    client.connect(server,5000);
    
    for(i=0;i<NO_OF_BYTES;i++)
    {
        TxMsg[i] = i;
    }
    
    while(!client.connected());
    
	if (client.connected()) {
		msgWriteLength = client.write(TxMsg, NO_OF_BYTES);
		Serial.println(msgWriteLength, HEX);
		client.flush();
	} 
	
}

void loop() {
}

I did some experiments and found that upto 6KB (plus few more hundred bytes) are able to transmitted in one client.wirte() call. If I increase the length of the data beyond that then according to rickkas7 it returns -16.

Can I increase the datasize to 8 KB or more? OR Do I have to stick to loop of 4KB bytes?

Thanks for your Support.

Kind Regards,
Iqram

This worked for me:

#include "Particle.h"

const size_t MAX_SEND_SIZE = 1024;

#define NO_OF_BYTES 8192


unsigned char TxMsg[NO_OF_BYTES];
unsigned int i, msgWriteLength = 0;
size_t sendOffset = 0;

byte server[] = { 192, 168, 2, 4 };

TCPClient client;

void setup() {
    Serial.begin(9600);
    client.connect(server,7123);

    for(i=0;i<NO_OF_BYTES;i++)
    {
        TxMsg[i] = i;
    }

    while(!client.connected());

}

void loop() {
	while(sendOffset < NO_OF_BYTES && client.connected()) {
		size_t requestCount = NO_OF_BYTES - sendOffset;
		if (requestCount > MAX_SEND_SIZE) {
			requestCount = MAX_SEND_SIZE;
		}

		int count = client.write(&TxMsg[sendOffset], requestCount);
		if (count > 0) {
			sendOffset += count;
			if (sendOffset >= NO_OF_BYTES) {
				// Done sending
				client.stop();
			}
		}
		else
		if (count == -16) {
			// Buffer full, resend same block again next time
		}
		else {
			Serial.printlnf("error %d", count);
			client.stop();
		}
	}
}

1 Like

@rickkas7 Thanks for your efforts. You are pushing 8912 bytes in the chunk of 1024 bytes every time.

I have few question here.

  1. Will this technique add the latency on data transmission on Air? Will it take same time as to transmit 8K in one shot?

  2. client.write() function waits till data gets transmitted or it posts the data and comes out?

  3. How can I measure the throughput of this kind of data transmission? (I already have asked this question in my another thread)

Thanks.!
Kind Regards,
Iqram

For all practical purposes, the data transfer speed and latency will be the same for 1024 byte writes and 8192 byte writes (if the latter worked). I can regularly send more than 800 Kbytes/sec for days using 1024 byte writes.

The client.write function copies the data to an internal buffer, then returns quickly. This is why 1K writes are actually faster and more reliable than 4K writes. If you wait until there’s 4K of free space in the buffer, it’s possible by the time your loop comes around again, the network buffer has completely emptied. By writing 1K at a time you can keep the buffer from running out of data to send (starvation).

I use custom code written in Java/JUnit to do most of my tests, but there are many network performance measuring tools available.

2 Likes

@rickkas7 Nice explanation for buffer size. Also, you have given nice pointer for through put measurement tools/utility.

Thanks for your great and quick support.

Kind Regards,
Iqram

I am back again on same thread with one more query :smile:

@rickkas7 I tried your given code and it is working perfectly fine :+1: .

But I am getting throughput of 2.5 to 3 mbps. I am sending data from photon client (TCP) to a server (Laptop). This local WiFi network is not connected to Internet. I was hopping that this will improve the throughput. It reduced the -16 return from client.write() function. But still I am seeing few -16 even I am writing 512 Bytes instead of 1024 bytes at one time.

Please provide your expert view on this behaviour. Is there any way to improve throughput from photon client?

Thanks.!
Kind Regards,
Iqram

One more data point. The client.RSSI() returns -45. The signal strength looks good but still throughput is very less. :frowning:

Please help me increasing it.

Thanks.!
Kind Regards,
Iqram

@Iqram, getting 2.5 to 3Mbps is very good speed actually. When you consider the protocol overhead and the processor speed, this is quite good. What speeds were you hoping to get?

Hi @Iqram

You might also want to try a speed test between two laptops in this configuration to see what the maximum achievable bandwidth is.

1 Like

Actually, you probably want to see the -16 errors for maximum throughput. The reason is that there’s an internal buffer that’s written to when you use client.write(). If your write will not fit in the buffer, you get a -16 error back. It’s not fatal, it just means that you’re keeping the buffer full.

Taken to the opposite extreme, say you set the writes to 32 bytes. You will never get a -16 error because the buffer will never fill up. You also won’t get full throughput because during the time it takes for loop to come around again and allow you to refill the buffer, the buffer completely empties out and sits idle.

You sort of have to tune the write size based on the network speed and the amount of time you spend in loop on average. I’ve found for simple tests it’s 1024. It’s rarely higher than that, but it’s usually between 512 and 2048.

2 Likes

Thank you @peekay123 for your reply . I am sorry for late reply.

I am looking for the throughput same as @rickkas7 (800 KB/sec = ~7Mbps). I was going through the TCP overhead and found that it will have maximum 60 bytes of overhead. You can confirm, since I am not expert in TCP it may be more.

Kind Regards,
Iqram

Hi @bko. This is good check for the network bandwidth availability check. Thank you for your suggestion.

I want to make one more point. There is only Photon client is connected to the WiFi router and the Server is connected to router through ethernet. Are you thinking of Wireless traffic on the channel on which Router is operating?

Thanks.!
Kind Regards,
Iqram

@rickkas7 Thank you for your explanation. I also had similar thought about -16 that if buffer is full, it is returning -16. Which in turn says that the throughput is low.

I am using same code what you gave me in your last post. I am only changing the size of the transfer in one go to 512 bytes. Is there any other way to increase throughput other then playing with max size?

Is there any hook to control WICED platform code in terms of buffer size or data rate etc?

Please suggest your views.

Thanks.!
Kind Regards,
Iqram

The Photon is a great device, but if you need to get more than 800 Kbytes/sec of data transfer, you’re looking at the wrong device. You need at minimum a Raspberry Pi or perhaps a ChromeBox/ChomeBook running Linux.

1 Like