Compiler difference between Build and Particle Dev

I have been trying to write a robust, minimal TCP client server example that is less trivial (and easier to read across to the real world) than the one in the documentation. My aim is to write something that will survive temporary loss of the cloud or local wifi. If someone already has this - great, please can we have a copy in “Getting Started”.

At the moment my simple code doesn’t survive temporary loss of wifi but needs a power cycle (as against reset) to recover. I’ll write to a separate topic about that when I have experimented a bit more.

I had limited success compiling with the particle dev system. This is what I usually use, but for moving backwards and forwards between two pieces of code for a pair of devices it crashed almost as often as the core/photon pair that were trying to talk to each other. Consequently I moved back to compiling using Particle Build.
The first thing that I found was that my code no longer compiled.
Build does not recognise:

TCPServer server = TCPServer(23);
server.printlnf("Elapsed time is: %f ",millis()/1000.0);

while particle dev is perfectly happy with it.
It is no great issue in itself but I had assumed that compiling using Build and particle dev would use the same compiler with the same quirks but clearly not. Is there a plan to harmonise compilers? How can we tell which compiler is more up-to-date and less quirky?

printlnf() - never seen that before.
printf(), of course.

maybe printlnf() is someone’s customization of how to have a printf() alike using special library code?

This isn’t a compiler issue - it’s a library issue.

here’s some code to add-on the usual printf()

#define PRINTF_OUT Serial // must elsewhere have Serial.begin(x) where x is, for Serial USB, any number
#include <stdarg.h>

// Here's the magic...
// macro printf in lieu of real stdin, stdout. 

#define printf(fmt, ...) pnprintf(PRINTF_OUT, 128, fmt, __VA_ARGS__)

char m[128];

void pnprintf(Print& p, uint16_t bufsize, const char* fmt, ...) {
   char buff[bufsize];
   va_list args;
   va_start(args, fmt);
   vsnprintf(buff, bufsize, fmt, args);

then use printf() as usual. Except a compiler config change may be needed to enable floating point. Depends on how uses the compiler.

PS: A nit: use integers where you can. In Arduino default compatibility (no floats)
Serial.println(millis()/1000); // no float. Floats are bad and to be avoided wherever possible.

1 Like

Thank you @stevech that is useful. I’d never seen printlnf() before either but it came up when I searched for the methods of the stream class and I was puzzled why it worked with one route and not the other.
Thank you too for the tip about avoiding floats where possible. In this case I wanted to generate a float to test out the TCP communications and the capabilities of client.write(), client.print(), client.printf() etc. Even worse than floats I’m making extensive use of sprintf() to put formatted data into a buffer for transmission.

It is the same with printf as printlnf, I just picked a more obscure example. Thank you for the workaround.

Build compiler:

simpletcpserver.cpp:64:16: error: 'class TCPServer' has no member named 'printf'
       else if (inChar=='f') {

Particle dev:

tick success!

Are you building with 0.4.5 or 0.4.6 in Particle Build?

1 Like

0.4.6 - no hang on a minute! I was programing an old core and it defaulted to 0.3.4

Now I’m using 0.4.6 everything is wonderful. Thank you. I had a nice little 0.4.6 box open on the cores tab but it was for a different core.
It may also explain why I couldn’t get a TCP client to work reliably.

1 Like