Unable to locate library files

Hi,

I'm trying to convert from PICs to Arduino and learn by example by downloading code for specific projects and adapting them for use. EG, my first project is to be an Aquarium controller, but rather than re-invent the wheel, have located a source code in the public domain. OK some of the components I probably won't use for my controller, but the thing that I find frustrating is that often or not the include files are not linked or contained in the zip files. I've been googling for the following, and would welcome any pointers as to their location

#include <Arduino.h>
#include <FormatDouble.h>

Trying to compile the code I get a an "fmtDouble was not declaired in this scope" error

#include <FormatDouble.h>

Trying to compile the code I get a an "fmtDouble was not declaired in this scope" error

If the library is not native you should include it with " " like this:

#include "FormatDouble.h"

The #include should be in the main sketch file (the .ino file) in addition to any other files where it might be required.

You have to install the library(s) in the right spot and then restart the IDE.

Hi guys, thanks for the input.

I'm aware of how to copy the library files to the library folder and restarting the IDE, what I'm struggling with is locating these library files on the net so I can install them... I'll try Hugo's suggestion to see if it compiles and runs

It's unusual for a library to not be self-contained. Can you give a link to a problem one? And show the code you are using to use that library?

You shouldn't need the quotes rather than brackets when including a library file. Does the file actually exist inside the library?

I'm struggling with is locating these library files on the net so I can install them

I don't see how changing #include "foo.h" to #include <foo.h> is going to help if you don't actually have foo.h. That's the point that isn't clear.

Hi Nick,

Here's the link to the guys site Arduino Aquarium: Source Code

and here is the hub link GitHub - RogerReed/Arduino-Aquarium: Arduino aquarium controller source code.

Hope that helps.

If you're struggling to locate a particular library used in a specific project then it may be more productive to contact the author of that project for support.

Hopefully they can tell you where to get the library. It may be one of their own for that particular sketch.

I've been googling for the following, and would welcome any pointers as to their location

#include <Arduino.h>

Arduino.h is part of the Arduino IDE.

As for FormatDouble, I can't find that either. You could write to the author.

However judging by this:

  fmtDouble(overflowTempSmoothed, 2, tempBuffer, 7);

All it does is take a double, and format it into a temporary buffer. You should be able to write your own replacement. sprintf on this platform doesn't support float/double but I'm sure there is a way, I just can't recall what it is right now.

This thread might help:

http://arduino.cc/forum/index.php/topic,44216

I find frustrating is that often or not the include files are not linked or contained in the zip files.

That particular author did not include the libraries (he probably assumed they were widely available).

Thanks for the further replies guys. I had posted the question on the authors blog site, so hopefully I may get a reply as further searching hasn't thrown up anything yet.

@Nick - I don't know about writing a substitute... I'm very much a newbie to this in terms of how the AVR works and the C style language...

Well, the function from the page I linked even has the same name, so you might guess that is the one you want. Remove the #include for FormatDouble, and just paste the code into your sketch (eg. near the bottom):

void fmtDouble(double val, byte precision, char *buf, unsigned bufLen = 0xffff);
unsigned fmtUnsigned(unsigned long val, char *buf, unsigned bufLen = 0xffff, byte width = 0);

//
// Produce a formatted string in a buffer corresponding to the value provided.
// If the 'width' parameter is non-zero, the value will be padded with leading
// zeroes to achieve the specified width.  The number of characters added to
// the buffer (not including the null termination) is returned.
//
unsigned
fmtUnsigned(unsigned long val, char *buf, unsigned bufLen, byte width)
{
  if (!buf || !bufLen)
    return(0);

  // produce the digit string (backwards in the digit buffer)
  char dbuf[10];
  unsigned idx = 0;
  while (idx < sizeof(dbuf))
  {
    dbuf[idx++] = (val % 10) + '0';
    if ((val /= 10) == 0)
      break;
  }

  // copy the optional leading zeroes and digits to the target buffer
  unsigned len = 0;
  byte padding = (width > idx) ? width - idx : 0;
  char c = '0';
  while ((--bufLen > 0) && (idx || padding))
  {
    if (padding)
      padding--;
    else
      c = dbuf[--idx];
    *buf++ = c;
    len++;
  }

  // add the null termination
  *buf = '\0';
  return(len);
}

//
// Format a floating point value with number of decimal places.
// The 'precision' parameter is a number from 0 to 6 indicating the desired decimal places.
// The 'buf' parameter points to a buffer to receive the formatted string.  This must be
// sufficiently large to contain the resulting string.  The buffer's length may be
// optionally specified.  If it is given, the maximum length of the generated string
// will be one less than the specified value.
//
// example: fmtDouble(3.1415, 2, buf); // produces 3.14 (two decimal places)
//
void
fmtDouble(double val, byte precision, char *buf, unsigned bufLen)
{
  if (!buf || !bufLen)
    return;

  // limit the precision to the maximum allowed value
  const byte maxPrecision = 6;
  if (precision > maxPrecision)
    precision = maxPrecision;

  if (--bufLen > 0)
  {
    // check for a negative value
    if (val < 0.0)
    {
      val = -val;
      *buf = '-';
      bufLen--;
    }

    // compute the rounding factor and fractional multiplier
    double roundingFactor = 0.5;
    unsigned long mult = 1;
    for (byte i = 0; i < precision; i++)
    {
      roundingFactor /= 10.0;
      mult *= 10;
    }

    if (bufLen > 0)
    {
      // apply the rounding factor
      val += roundingFactor;

      // add the integral portion to the buffer
      unsigned len = fmtUnsigned((unsigned long)val, buf, bufLen);
      buf += len;
      bufLen -= len;
    }

    // handle the fractional portion
    if ((precision > 0) && (bufLen > 0))
    {
      *buf++ = '.';
      if (--bufLen > 0)
        buf += fmtUnsigned((unsigned long)((val - (unsigned long)val) * mult), buf, bufLen, precision);
    }
  }

  // null-terminate the string
  *buf = '\0';
}

Example of doing exactly that, with a test inside setup:

void fmtDouble(double val, byte precision, char *buf, unsigned bufLen = 0xffff);
unsigned fmtUnsigned(unsigned long val, char *buf, unsigned bufLen = 0xffff, byte width = 0);

//
// Produce a formatted string in a buffer corresponding to the value provided.
// If the 'width' parameter is non-zero, the value will be padded with leading
// zeroes to achieve the specified width.  The number of characters added to
// the buffer (not including the null termination) is returned.
//
unsigned
fmtUnsigned(unsigned long val, char *buf, unsigned bufLen, byte width)
{
  if (!buf || !bufLen)
    return(0);

  // produce the digit string (backwards in the digit buffer)
  char dbuf[10];
  unsigned idx = 0;
  while (idx < sizeof(dbuf))
  {
    dbuf[idx++] = (val % 10) + '0';
    if ((val /= 10) == 0)
      break;
  }

  // copy the optional leading zeroes and digits to the target buffer
  unsigned len = 0;
  byte padding = (width > idx) ? width - idx : 0;
  char c = '0';
  while ((--bufLen > 0) && (idx || padding))
  {
    if (padding)
      padding--;
    else
      c = dbuf[--idx];
    *buf++ = c;
    len++;
  }

  // add the null termination
  *buf = '\0';
  return(len);
}

//
// Format a floating point value with number of decimal places.
// The 'precision' parameter is a number from 0 to 6 indicating the desired decimal places.
// The 'buf' parameter points to a buffer to receive the formatted string.  This must be
// sufficiently large to contain the resulting string.  The buffer's length may be
// optionally specified.  If it is given, the maximum length of the generated string
// will be one less than the specified value.
//
// example: fmtDouble(3.1415, 2, buf); // produces 3.14 (two decimal places)
//
void
fmtDouble(double val, byte precision, char *buf, unsigned bufLen)
{
  if (!buf || !bufLen)
    return;

  // limit the precision to the maximum allowed value
  const byte maxPrecision = 6;
  if (precision > maxPrecision)
    precision = maxPrecision;

  if (--bufLen > 0)
  {
    // check for a negative value
    if (val < 0.0)
    {
      val = -val;
      *buf = '-';
      bufLen--;
    }

    // compute the rounding factor and fractional multiplier
    double roundingFactor = 0.5;
    unsigned long mult = 1;
    for (byte i = 0; i < precision; i++)
    {
      roundingFactor /= 10.0;
      mult *= 10;
    }

    if (bufLen > 0)
    {
      // apply the rounding factor
      val += roundingFactor;

      // add the integral portion to the buffer
      unsigned len = fmtUnsigned((unsigned long)val, buf, bufLen);
      buf += len;
      bufLen -= len;
    }

    // handle the fractional portion
    if ((precision > 0) && (bufLen > 0))
    {
      *buf++ = '.';
      if (--bufLen > 0)
        buf += fmtUnsigned((unsigned long)((val - (unsigned long)val) * mult), buf, bufLen, precision);
    }
  }

  // null-terminate the string
  *buf = '\0';
}


void setup ()
  {
  Serial.begin (115200);

  // test
  
  char buf [20];
  
  fmtDouble(3.1415, 5, buf);
  
  Serial.println (buf);
  }  // end of setup

void loop ()
  {
    
  }  // end of loop

I turned that function into a library, so you can just go ahead with the original code now.

Download from:

http://gammon.com.au/Arduino/FormatDouble.zip

Install in the usual way.

Test:

#include <FormatDouble.h>

void setup ()
  {
  Serial.begin (115200);
  char buf [20];
  fmtDouble(3.1415, 5, buf, sizeof buf);
  Serial.println (buf);
  }  // end of setup

void loop () { }

I'm not promising it works perfectly, I didn't look at the function that closely. But my test works. :slight_smile:

Thanks Nick.

I've been away from the board for a few days. In desperation to get the project off the ground I've dusted off my EasyPIC5 board and went back to programming in PicBASICpro :blush: I may revert back and give the Arduino another run, but feel (for me with my limited level of programming skills) that hunting for library files, the structure and syntax of the programming language frustrating.

Hi Nick,
thank you very much for this working library. I tried to google up float to string conversion and seems its not standardized anywhere, which surprises me, because for data logging its very useful.

Anywho, I have two questions towards your implementation in FormatDouble.h

  1. I noticed, it loses minus sign for negative values. Would it be hard to include that?
    fmtDouble(-3.1415, 2, buf, sizeof buf); would give -3.14

  2. I dont understand the char buf [20]; size. For 3.14 you should need 5 char string no?
    But in your case, actually 6 is necessary, char buf [5] gives me only 3.1 with
    your example.

Thanks

You could use dstrtof which I discovered after doing that library.

  1. I dont understand the char buf [20]; size. For 3.14 you should need 5 char string no?

Just being cautious in case someone tried more decimal places without realizing the importance of the buffer size.

Thanks, I originally googled dstrtof, but could not make it work. Your explanation works nicely. Though this one puts extra space in front of string if buffer is bigger than what you put in it, but on the opposite side if buffer is too small it still gives all characters you ask for, so it works just fine.

kingbean:

  1. I noticed, it loses minus sign for negative values. Would it be hard to include that?
    fmtDouble(-3.1415, 2, buf, sizeof buf); would give -3.14

I think I have figured out how to fix the negative value issue. There is a line in void fmtDouble() that says:

*buf = '-';

after that place this code:

buf += 1;

Here is the complete code with example:

void fmtDouble(double val, byte precision, char *buf, unsigned bufLen = 0xffff);
unsigned fmtUnsigned(unsigned long val, char *buf, unsigned bufLen = 0xffff, byte width = 0);

//
// Produce a formatted string in a buffer corresponding to the value provided.
// If the 'width' parameter is non-zero, the value will be padded with leading
// zeroes to achieve the specified width.  The number of characters added to
// the buffer (not including the null termination) is returned.
//
unsigned fmtUnsigned(unsigned long val, char *buf, unsigned bufLen, byte width)
{
  if (!buf || !bufLen)
    return(0);

  // produce the digit string (backwards in the digit buffer)
  char dbuf[10];
  unsigned idx = 0;
  while (idx < sizeof(dbuf))
  {
    dbuf[idx++] = (val % 10) + '0';
    if ((val /= 10) == 0)
      break;
  }

  // copy the optional leading zeroes and digits to the target buffer
  unsigned len = 0;
  byte padding = (width > idx) ? width - idx : 0;
  char c = '0';
  while ((--bufLen > 0) && (idx || padding))
  {
    if (padding)
      padding--;
    else
      c = dbuf[--idx];
    *buf++ = c;
    len++;
  }

  // add the null termination
  *buf = '\0';
  return(len);
}

//
// Format a floating point value with number of decimal places.
// The 'precision' parameter is a number from 0 to 6 indicating the desired decimal places.
// The 'buf' parameter points to a buffer to receive the formatted string.  This must be
// sufficiently large to contain the resulting string.  The buffer's length may be
// optionally specified.  If it is given, the maximum length of the generated string
// will be one less than the specified value.
//
// example: fmtDouble(3.1415, 2, buf); // produces 3.14 (two decimal places)
//
void fmtDouble(double val, byte precision, char *buf, unsigned bufLen)
{
  if (!buf || !bufLen)
    return;

  // limit the precision to the maximum allowed value
  const byte maxPrecision = 6;
  if (precision > maxPrecision)
    precision = maxPrecision;

  if (--bufLen > 0)
  {
    // check for a negative value
    if (val < 0.0)
    {
      Serial.println("Negative value!!!!");
      val = -val;
      *buf = '-';
      buf += 1;
      bufLen--;
    }

    // compute the rounding factor and fractional multiplier
    double roundingFactor = 0.5;
    unsigned long mult = 1;
    for (byte i = 0; i < precision; i++)
    {
      roundingFactor /= 10.0;
      mult *= 10;
    }

    if (bufLen > 0)
    {
      // apply the rounding factor
      val += roundingFactor;

      // add the integral portion to the buffer
      unsigned len = fmtUnsigned((unsigned long)val, buf, bufLen);
      buf += len;
      bufLen -= len;
    }

    // handle the fractional portion
    if ((precision > 0) && (bufLen > 0))
    {
      *buf++ = '.';
      if (--bufLen > 0)
        buf += fmtUnsigned((unsigned long)((val - (unsigned long)val) * mult), buf, bufLen, precision);
    }
  }

  // null-terminate the string
  *buf = '\0';
}


void setup ()
  {
  Serial.begin (9600);

  // test
  
  char buf [20];
  
  fmtDouble(31.1415, 5, buf);
  
  Serial.println (buf);
  }  // end of setup

void loop ()
  {
    
  }  // end of loop

Again, thanks nickgammon for his collaboration :slight_smile: