I have developed an application which needs to send about 10KB of data to a server (as a single file). On a Photon, and using an FTP server, it took about 7 seconds which is too long for me. On the Electron, it took "for ever" and was not feasible.
On advice of @Scruffr, I rewrote the application to use a TCP server instead. The results on the Photon were extremely significant ( < 200 ms) which is of course a major improvement over 7 seconds for the FTP server.
On the Electron, the same file took TWO MINUTES!
Am I doing something wrong or is the Electron designed to just send one value at a time?
I am sending chunks less than 100 bytes each time. (TCP)
When I was doing FTP, I was sending chunks of 512 bytes each time but the file never arrived even though I could see that the Electron hooked up to the FTP server.
Side note: I am not sure the Electron is reporting correct signal strength numbers because I know that cell service in my area is weak. My phone barely gets 1 bar so I am not putting too much faith in what the Electron is reporting β¦
How does the Electron behave when you try it with 512 byte at a time?
Can you post your code or a SHARE THIS REVISION link.
How are you receiving the data?
I have not tried sending fixed (512) chunks as the same code worked successfully with the Photon and takes well less than half a second to send the data.
I am receiving the data with my own TCP Server (written in .NET).
The code on the Electron (Photon) is below. I am sending a three-dimensional array of integers from memory.
You may be missing some important points between Photon and Electron.
Apart from the inherently slower and more "vulnerable" transport via cellular compared to WiFi, the communication between the STM32 and ublox cellular modem goes via relatively slow serial interface while on the Photon the communication goes via a considerably faster bus.
Also the Electron communicates with the cellular provider on a UDP based protocol while the Photon works natively on TCP.
Also the TX buffer of the Photon can send chunks of up to 1024 byte, the Electron only 512.
Consequently the max transfer rate on the Electron will undoubtedly be slower than on the Photon, but if the difference gets that severe you need to reduce as much of the impact caused by your own code as possible since you can't do anything about the inherent differences.
In your code I also see some problematic portions
e.g.
here you are declaring msg1 one byte too short.
Although there is no need to actually copy the string into the byte array, you can just write it that way
You may also have frequently read that we keep discouraging the use of String and rather suggest to use snprintf() to create formatted strings.
However, when you are sending your data to a self-written TCP server, why not just send the raw binary data and convert it on the receiving end?
That would cut down on transfer data and time tremendously.
The reason my code is inefficient is because I know very little about C so I would really appreciate your help with those two simple questions so I can modify my code:
How does one use snprintf()? I need to send the following:
I useful read in order to understand snprintf() is this http://www.cplusplus.com/reference/cstdio/printf/ snprintf() uses the same logic, but "prints" its output to a character buffer with a given max size.
For your specific string you'd do it this way (assuming all your variables are int
char msg[128];
snprintf(msg, sizeof(msg), "%d,%d,%d\r\n", i, cloudP[j][i][0], cloudP[j][i][1]);
Lets suppose - since your code snippet does not reveal the actual info - you want to send your cloudP array which is a three dimentional array of uint16_t values not exceeding a total of 512 bytes, it would just be done this way
That's it.
On the receiving end you need to fill the incoming data into a struct that allows you to retrieve the respective values correctly, but that's a VB.Net question - it's doable there to but I do prefer C#.
You need the typecast ((const uint8_t*)) to convince the compiler that the array you are passing to the function can in deed be considered as valid parameter despite it being declared differently.
Since you don't want to send 128 bytes (= sizeof(msg)) but rather only the portion of the array that contains the string, all the bytes after that should not be sent.
That's why I so elaborately introduced my code snippet this way
If your array is longer, you'd just need to "chop it up" into chunks and send them one-by-one, as I mentioned earlier.
I am just wondering why would sending the raw array be faster since the byte conversion is done by the main processor before sending it to the modem (as you had explained earlier, sending to the blox modem is where the bottleneck is) β¦?
There is no conversion taking place at all - hence "raw".
Based on the assumption (since you still haven't reavealed the actual declaration of cloudP) that your array is an array of a numeric datatype and as such the byte count to transfer any arbitrary number in its binary form is statistically less than what the same number would take in its "printed" form (byte x = 123 takes one byte raw but 3+1 characters to print). You also won't add any extra bytes by injecting text or separators.
And exctly that reduction of bytes to transfer would inevitable also reduce the time to do so.
With the declaration of your array above, the max index for your third dimension would be [0] since you declare it to only have 1 element.
You don't declare the max index but the number of elements per dimension and the index always starts with 0.
When saving transfer "cost" what are your expected max values for each element in your field. unsigned long takes up 32 bit, so you can store values in the range of 0 .. 4294967296. If you don't need that large numbers you may want to consider shorter datatypes (e.g. uint16_t max 65535) which again would reduce data consumption drastically.