Calculator project with char array I/O - conversion problem

Hi, I am building a calculator using Adafruit Feather M0, 14 segment 16 character display and a matrix keyboard.
I use char arrays to store input from the keyboard and then covert to double variables for the calculations. E.g:
myDoubleVar = strtod(keyNumChar,NULL);
This works fine, but I am stuck with converting doubles back to char arrays so I can send the results to the display.
dtostr does not seem to be supported.

I also tried dtos and strcopy
String varAsString = dtos(myDoubleVar);
strcopy(keyNumChar, varAsString.c_str());
neither of these is supported.

Any suggestions of how I can convert a double float to a char[] ?
Thanks, Gordon.

double to ascii --> dtoa() function

Thanks for your suggestion, but dtoa is not supported. I get the message:
"'dtoa' was not declared in this scope; did you mean 'ltoa'?"
Is there a library I need to include? If there is can you please give the exact #include command I need to use.
Thanks.

How are you printing to the display. If using a library (which ?) does it not support the printing of floating point variables ?

More details please

I'm using Adafruit 0.54" Quad Alphanumeric FeatherWing Displays with I2C interface and the libraries:
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"

I am new to Arduino and have little experience of C/C++

In the example sketches Adafruit give ASCII and Raw functions for writing to the display 1 digit at a time e.g.
alpha4.writeDigitRaw(digitNum, 0x3FFF); // Raw bitmap of the LED segments
alpha4.writeDigitAscii(digitNum, '8'); // Ascii character to a display digit

I am using the ASCII version.
I don't know which GFX commands (if any) can be used with this display, but I had to put 4 displays together for 16 digits which means using 4x I2C addresses each with 4 digits and a different object for each 4-digit display (alpha1, alpha2, alpha3, alpha4)
Maybe a different display would be easier, but I chose this one as the 14 segment display is like the HP-41C calculator!

So a dtoa or dtostr funtion would fit into the software I have written, but if there is a way to print double numbers that would be best!

Is there documentation giving a list of commands and syntax for each of the libraries?

Please post a simple but complete example of how you print a char array to the display. It is very likely that you can simply use the print() function to output a float directly instead of an array of chars, presumably terminated with a '\0' to turn it into a C string

The display buffer is filled with spaces where no char is required.
Each digit has its own decimal point and dP[] is used to turn on/off any decimal point.

chardisplayBuffer[16];
bool dP[16];

void writetodisplay()
{
// Write the buffer to the display
alpha74.writeDigitAscii(0, displayBuffer[0], dP[0]);
alpha74.writeDigitAscii(1, displayBuffer[1], dP[1]);
alpha74.writeDigitAscii(2, displayBuffer[2], dP[2]);
alpha74.writeDigitAscii(3, displayBuffer[3], dP[3]);
alpha74.writeDisplay();
alpha73.writeDigitAscii(0, displayBuffer[4], dP[4]);
alpha73.writeDigitAscii(1, displayBuffer[5], dP[5]);
alpha73.writeDigitAscii(2, displayBuffer[6], dP[6]);
alpha73.writeDigitAscii(3, displayBuffer[7], dP[7]);
alpha73.writeDisplay();
alpha72.writeDigitAscii(0, displayBuffer[8], dP[8]);
alpha72.writeDigitAscii(1, displayBuffer[9], dP[9]);
alpha72.writeDigitAscii(2, displayBuffer[10], dP[10]);
alpha72.writeDigitAscii(3, displayBuffer[11], dP[11]);
alpha72.writeDisplay();
alpha71.writeDigitAscii(0, displayBuffer[12], dP[12]);
alpha71.writeDigitAscii(1, displayBuffer[13], dP[13]);
alpha71.writeDigitAscii(2, displayBuffer[14], dP[14]);
alpha71.writeDigitAscii(3, displayBuffer[15], dP[15]);
alpha71.writeDisplay();
}

I am not familiar with the library but the backpack library has a method to print a float

void Adafruit_7segment::printFloat(double n, uint8_t fracDigits, uint8_t base)

Give it a try

Using
alpha4.printFloat(stack[1], 2, 10)
I get the error message
'class Adafruit_AlphaNum4' has no member named 'printFloat'

However println works for integers
alpha4.println(counter);

BUT unfortunately the segment digits do not fully map from 7-segment to 14-segment.
The centre bar is split on the 14 segment display and half of it lights up, the other half lights up instead if the decimal point!

Anyway printFloat() does not really make sense when limited to a 4 digit display and something much more sophisticated is needed to run the conversion over 4 objects each with 4 digits.
I will take the library code for printFloat() and see if I can reuse it. Unless someone comes up with a C++ library function.
Thanks for your help.

Please post your complete sketch

I haven't searched for a real documentation.
The mimimum what is always available is the sourcecode.
And in some cases the source-code is sufficient to use it as "documentation".
Though I admit that in most cases it is not sufficient to look into the sourcecode.

It would be convenient if there would be different functions for displaying values of different variable types.
For this looking in the sourcecode is promising.
finding the sourcecode online works like this

google for "Github" + your words of interest.
In your case the name of the used library

https://www.google.de/search?as_q=github+Adafruit_LEDBackpack.h

which quickly finds the GiPo (my short for Github repository)

and there you look up the file Adafruit_LEDBackpack.h

/Adafruit_LEDBackpack.h

and voila inside this file you find all the defined functions which include

void printFloat(double n, uint8_t fracDigits = 2, uint8_t base = DEC);

by searching for "float" you will find all functions that deal - somehow - with floats
and you will find

/*!
    @brief  Print double-precision float value to 7-segment display.
    @param  n       Numeric value.
    @param  digits  Fractional-part digits.
  */
  void print(double n, int digits = 2);

this gives a rough oveview how to use these functions.

well if you give a typical example of how the numbers look like the users here can make suggestions how you can code this.

This is something newcomers seems to need a very long time to understand:
coding starts with normal words / normal numbers

in the sense of writing down in normal words - and by avoiding any progamming/coding-terms

The answer to the question: What is the desired functionality?

In your case:
showing numbers like

-123456789.123456

on a 16-digit 14-segment-display

As the 16 digit display is divided into 4 4digit displays the complete number has to be separated into
-123
4567
89.12
3456

Programming this is a step by step process.
convert the float into an array of char because in an array of char each digit is easier to access.

It might be that you don't know yet what arrays of chars are.
So you just do a coding-interrupt learning arrays of char

I recommend this learning by using small testprograms that do just a few things
like setting up a easy to analyse demofloat like
-123.4567
and then coding convert example float to a array of char and print the array of char
to test if it works like it should

next step coding a function that takes each digit and put the digit into its group

You will hav to test this functions with all numbers that can occur
0
0.1
-0.1
0.0000000001
-0.0000000001
12.3
-12.3
etc.
step by step learning how to modify the code so the final code can deal with all numbers correctly.

In this process whenever you don't understand anything you ask it here in the forum by providing each time a complete test-sketch and its serial output.
I'm sure that this kind of questions is enjoyable to answer to quite a lot of users.

depending on the minimum and the maximum numbers you need the solutions look different.

So it is up to you to define the smallest value and how this smallest number schould appear on your display and defining the biggest value and how this biggest value shall be shown on your display

best regards Stefan

Hi Stefan,
Thanks for your detailed reply.
As I am building a scientific calculator as a project to entertain myself, the requirement is for as much precision as I can get with no restrictions on the number range to be used.
My requirement is to convert a double float into a char array so I can display it on a 16 digit display. The display I have chosen requires a char array. I have been surprised that I have not been able to find a C++ function that supports this requirement in the Arduino environment.

I have looked at the Adafruit library source code after UKHeliBob's replies.
The printFloat() function only works with 7 segment displays and not the 14 segment. (I tested it this morning).

I will take your advice and write a sketch just to test the display functionality, as posting all of the 450 lines here would not be productive. Then I can post it here.

Gordon.

You can use dtostrf() but you need to include this at the top of your sketch

#include <avr/dtostrf.h>

void setup() {
  // put your setup code here, to run once:

  float val = 3.14159;
  char buff[20];
  dtostrf(val, 4, 6, buff);  
}

void loop() {
  // put your main code here, to run repeatedly:

}

Thank you for your informative reply, that works for floating point numbers, I haven't tried scientific notation yet.

From the library:
char *dtostrf (double val, signed char width, unsigned char prec, char *sout);

Is it possible to leave the signed char width and unsigned char precision parameters unspecified so that the result matches the double val width and precision?

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.