plotly / arduino-api

Arduino library for real-time logging and streaming data to online plotly graphs

Home Page:https://plot.ly/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

avr/dstrtof.h No such file or directory in Arduino 1.6

vicatcu opened this issue · comments

Reference issue #3. Possible duplicate of issue #34 (though we come to different conclusions).

Arduino made a pretty big change (not too long ago) in the compiler toolchain moving from the Arduino 1.0 branch to the Arduino 1.6 branch (which is now the mainline). Arduino 1.0.6 shipped with avr-gcc version 4.3.2 and AVR-Libc 1.6.4, and Arduino 1.6.0 ships with avr-gcc version 4.8.1 and AVR-Libc 1.8.0.

Net result, if you try and compile in 1.0.6 you get no errors, but if you try and compile in 1.6.0 you get:

fatal error: avr/dtostrf.h: No such file or directory
 #include <avr/dtostrf.h>

The weird thing is I don't know how it compiles in 1.0.6 because I can't find such a file in the 1.0.6 directory structure either, and dtostrf definitely seems to be part of stdlib.h, not this mythical avr/dtostrf.h.

In fact, if I merely comment out the #include <avr/dtostrf.h> it still compiles fine in both 1.0.6 and 1.6.0. Even seems to work 👍. Note I'm using Ubuntu 14.04 64-bit, fwiw.

Great to know, thanks. Let me give a few things a try and I'll get back to you!

@vicatcu I'm getting the same issues as you. It looks like if you have standard C build tools, avr comes with a dtostrf library, and Arduino just grabs it from there. On the new 1.6 IDE, it seems like they changed a few things and it's not working like before. I put in a hacky replacement function for dtostrf, and it compiles, but I'm still having trouble piping data out.

I'll get back to you ASAP as I have more. For now, if it is time-critical, perhpaps use an older version until we can get this sorted. Sorry for the inconvenience!

OK, correction, it did work. It just took about 20-30 seconds to start streaming. Will keep you posted.

I have the same problem with Arduino 1.6.1.
I located the dtostrf.h file in the
C:\Program Files (x86)\Arduino\hardware\arduino\sam\cores\arduino\avr
In my configuration there are two subtrees in the hardware\arduino folder:

  • sam
  • avr

There is no cores\arduino\avr in the avr subtree. So, I created this folder and copied these files in there.

  • dtostrf.h
  • dtostrf.c

So, I have them added in here:
C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino\avr
With these steps it is compiling now!!!!!
If you don't have those file you may look for them in here (similar file tree structure I described above) :
https://github.com/arduino/Arduino/tree/master/hardware/arduino

I have the same problem and as @equihuam says, coping the files the example compiles, but I don't check if it works as in Arduino IDE version 1.0.6.
If you copy all avr directory from C:\Program Files (x86)\Arduino\hardware\arduino\sam\cores\arduino\ you get another error.
I'll test if this fix the poblem.

Yup, lots of very bad code was able to compile in 1.0.6, because missing .h files weren't treated as actual errors.

Have you tried simply commenting out the #include line?

Thank you @PaulStoffregen it works, now I understand why there is no problem with version 1.0.6, despite of file dtostrf.h doesn't exists and it's referred in the library..

@PaulStoffregen I'm pretty sure commenting out the #include line works (actually that was my suggestion in the creation of the issue. :-)

It looks like we should just include our own dtostrf function, something like:

char *dtostrf (float val, signed char width, unsigned char prec, char *sout) {
  char fmt[20];
  sprintf(fmt, "%%%d.%df", width, prec);
  sprintf(sout, fmt, val);
  return sout;
}

and then 💥 the include statement. @vicatcu @jecrespo @PaulStoffregen have you tried this? If this works, could you make a PR update?

I wouldn't recommend that.

Long-term, your own dtostrf is just asking for conflicts with the standard library.

I've checked both 1.0.5 and 1.6.4, and in both versions dtostrf() is declared in stdlib.h for AVR (which is included by Arduino.h already). No sign of any dtostrf.h there.

However, for the SAM core, there is an avr/dtostrf.h file available with a corresponding implementation in avr/dtostrf.c, presumably because dtostrf() is an avr-libc specific function, not available in the SAM libc, but Arduino's WString class needs it.

I think this leaves a few options:

  1. Remove the dtostrf.h include. This fixes AVR, but breaks SAM and other platforms that do not provide dtostrf() in the standard library.
  2. Keep the include only for SAM (or perhaps better, for all non-AVR architectures). This fixes AVR, and keeps SAM (and any other (third-party) architecture/core that does not provide dtostrf() in the standard library, but does have a custom dtostrf.h in the Arduino core) working.
  3. Use some other float-to-string conversion function. It seems that snprintf is the de-facto standard, but printf on AVR doesn't support floats. I suspect there might not be other alternatives.
  4. Use the Arduino String class for conversion. This moves the responsibility of sorting out this mess to the Arduino core, which can decide to use dtostrf() if it's available on the platform, or do whatever it needs to get this working. Downside here is that this uses dynamic memory for the string, but since this will be just a short-lived String instance, it should only add a bit of CPU overhead, not cause memory fragmentation or problems.
  5. Add your own float-to-string implementation (but not based on the printf, like @chriddyp proposed, and not named dtostrf() to prevent conflicts) and use that on all platforms unconditionally. This might actually be the easiest approach, especially if it doesn't have to be a generic implementation, but just one that always has three digits (like all uses of dtostrf() currently, AFAICS).

Option 2 is the easiest, option 4 and 5 seem to be the most portable. Any of these seem fine to me (as does option 3, if someone knows some standard, usable, function I missed?).

post moved to: #51
(Specified folder/zip file does not contain a valid library)

@eyesofahunter It seems your problem is completely unrelated to this issue, so you probably should not have replied here. Instead, opening up a separate issue, or perhaps contacting plotly support would have been better. Did you see the note in the README that this library only works with 1.0.3 or 1.0.5?

Hi,
I'm having the same issue of "avr/dtostrf.h: No such file or directory". I commented out the include part, but that didn't solve the problem. Then I thought this is due to some new updates? I'm currently working with Arduino 1.7.7. Someone with similar problems and has a solution for this? Thanks.

Maybe you downloaded from the wrong Arduino website? 1.7.7 sounds like something from Arduino dot org. (even though they're calling it "1.7.7", it's really a copy of version 1.6.1 with names changed and a few minor edits)

The real Arduino software comes from Arduino dot cc. 1.6.5 is the latest version.

This should not be too difficult: https://www.arduino.cc/reference/en/language/variables/data-types/stringobject/


String stringOne = "Hello String";                                     // using a constant String
String stringOne =  String('a');                                          // converting a constant char into a String
String stringTwo =  String("This is a string");                 // converting a constant string into a String object
String stringOne =  String(stringTwo + " with more"); // concatenating two strings
String stringOne =  String(13);                                          // using a constant integer
String stringOne =  String(analogRead(0), DEC);          // using an int and a base
String stringOne =  String(45, HEX);                                // using an int and a base (hexadecimal)
String stringOne =  String(255, BIN);                               // using an int and a base (binary)
String stringOne =  String(millis(), DEC);                        // using a long and a base
String stringOne =  String(5.698, 3);                                // using a float and the decimal places