Use of standard C libraries like stdio

Hi,

I want to port some of my programs to the Spark, but I find Spark is much different to standard C.
So I have a few questions about compatibility:

Is it possible to use all the C standard libs (stdlib, stdio, string, …) ?

Is there a way to use the C stream IO (like stdio) for serial ?

Many libraries use Serial.print or something for debugging. Is it possible to route Serial to Serial2 (hardware Uart) without modifying all the libraries code? Or what can be a more generic way to output strings to a dynamic “stream”?
Maybe like this (pseudocode, I don’t know how to do this for real):

stout=Serial; // or Serial2 or Telnet or whatever
stout.Print(“Hallo”);

The Serial-USB is bad for debugging with windows because everytime you reset the core, your terminal program (Putty) disconnects because the port disappears.

Can the Spark Serial Class be expanded with a printf function. I did my own serial_printf now, like described here in the community, but nicer would be a class function Serial.printf.

Thanks
Thorsten

Hi @Bluescreen

I think these C libs are available but you may not want to use them. Spark is based on the Arduino Wiring language and has a lot of that structure baked in already, so you if you use other IO (even sprintf() ) it can take away a lot of your available code space. Lot of folks have found that avoiding sprintf() and using more primitive things like itoa() allows them to fit more code and get their app to fit.

In Arduino land, the common base class for serial streams is called Stream and so you could something like this (this is just example code, I haven’t tested it):

Stream *myStream;
//...
if (test1) {
  myStream = Serial;  //usb
} elseif (test2) {
  myStream = Serial1;  //hardware USART on core RX/TX pins
} else {
  myStream = Serial2;  //hardware USART on D0/D1 pins
}
myStream->begin(9600);
//...
myStream->print("Hello world!");

Finally using a template, you can get the << syntax easily if that is easier to type.

http://playground.arduino.cc/Main/StreamingOutput

2 Likes

Thank you for your description of the stream class. I will give it a try.

But the concerns about printf eating up to much code space is only partly correct. If you have a fullsize implementation of printf that will be right, but you can create a smaller one if you reduce it to integer, character and string.
Then you might get even smaller code when you write a longer printf than when writing tons of serial.print’s. Don’t forget, each call to a subroutine also needs codespace.

But the main thing is: I am not from Arduinoland. So it is very difficult for me to learn all that “exotic” stuff. I programmed for years on AVRs using WinAVR and so have many libraries and code snippets. Most of them are not usable in Arduinoland without working on them. I can even test my code on the PC.
I never understood why the Arduino guys didn’t use the standard C/C++ constructs, and simply build a nice Arduino lib with all that nice stuff in what makes the Arduino.

Sorry, but that does not work.

At the “myStream = Serial” line I get the following error:

…/applications/matrixclock/application.cpp: In function ‘void setup()’:
…/applications/matrixclock/application.cpp:29:5: error: cannot convert ‘USARTSerial’ to ‘Stream*’ in assignment
myStream=Serial1;
^
make[1]: *** [obj/applications/matrixclock/application.o] Error 1
make[1]: Leaving directory `D:/Entwickl/Spark/CORE-F~1/build’
make: *** [all] Error 2

The error message is quite clear about the reason

Have you tried it with

if (test1) {
  myStream = &Serial;  //usb
} elseif (test2) {
  myStream = &Serial1;  //hardware USART on core RX/TX pins
} else {
  myStream = &Serial2;  //hardware USART on D0/D1 pins
}

In this case you'd have to do ... .begin(9600); inside the respective if branches, since Stream class does not provide a begin() method.

2 Likes

Ok, so it is working. Thank you.
But I really would like to use the standard C implementation of stream IO because I have many libraries I want to use, that are based on that.

So I simply tried to do a “puts(“hello”)” but get tons of errors. But I don’t know how to initialize the stdout stream, maybe that’s the reasing. It would be nice to look into the libc source, but I don’t find it.

Hi @Bluescreen

Sorry I left off the & in the code above–glad that @ScruffR got it sorted for you.

I don’t know how much of stream IO will fit in the memory available on the core. If you are just looking for the syntactic sugar to ease porting, you can do this:

template<class T> inline Print &operator <<(Print &obj, T arg) { obj.print(arg); return obj; } 

Which allows this to work:

Serial << "Current GPS Position " << longitude << " " << latitude << ".";

@Bluescreen, as @bko mentioned memory will become an issue.

But if you can boil the missing functions down to just a few major ones, than you could either add them yourself :wink:
If you do build locally, just extend the spark_wiring_print.c/.h to add your missing functions, or
if you are on WebIDE and only need very few funcs, you could even try a somewhat ugly “quirkaround” like this to add puts()

#define puts(s) write(s)

...

  myStream->puts("Test this");