My first project. Help.

Hello guys ! I need help with understanding and adding floats to my input .
I trying to make a calculator and using old calculator case and keyboard which i have .
I'm not so experienced in arduino and c++. The knowlege i have is from arduino tutorials I've watched
and the only calculator i can make is from the serial monitor which is easy .
so i bought a compatable with the calculator case display which is i2c oled 0.91 inch display and i remaked the keyboard so i can use the #include <Keypad.h> and it was kind of big success for me then i tried to make something but with no success i mean it displayed the digits from 1 to 9 but that was all so i decided to find any sketch and modify it a bit so it can fit to the thing I want to make.
and found a sketch "arduino calculatro by mission criticall" and modified it a bit and its working .
So i don't know how to make the numbers in input like 1.65, 22.6 etc.
Can anyone help me with this I don't know what to put in the code i mean i have no idea how i can add the " . " to my input number . Thanks in advance !!
I'm using arduino nano
keypad
and i2c oled 0.91 inch
here is the full code

#include <Keypad.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

#if (SSD1306_LCDHEIGHT != 32)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

const byte numRows= 5; //number of rows on the keypad
const byte numCols= 4; //number of columns on the keypad

//keymap defines the key pressed according to the row and columns just as appears on the keypad
char customKey;

double first = 0;
float second = 0;
//long second = 0;
double total = 0;
char Operator;
bool equalPressed=false;
bool showFirst = false;
bool isDecimal1=false;
float decimals1=10.0;
bool isDecimal2=false;
float decimals2=10.0;

char keymap[numRows][numCols]= 
{
 {'Q','E','%','x'},

  {'7','8','9','/' },

  {'4','5','6','-'},

  {'1','2','3','+'},

  {'C','0','.','='},
  
};

//Code that shows the the keypad connections to the arduino terminals
byte rowPins[numRows] =  {2, 3, 4, 5, 6}; //Rows 0 to 3
byte colPins[numCols]= {7, 8, 9, 10}; //Columns 0 to 3

//initializes an instance of the Keypad class
Keypad customKeypad= Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols);

void showSplash() {
  String splashString="CUSTOM GREEN LINE";
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.setCursor(64-(splashString.length()*3),0);
  display.print(splashString);
  display.setTextSize(2);
  splashString="commodore";
  display.setCursor(64-(splashString.length()*6),16);
  display.print(splashString);
  display.display();
  delay(3000);
}

void setup()
{
  Serial.begin(9600);
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3D (for the 128x64)
  showSplash();
  display.print("commodore calculator");
  display.setTextSize(2);
  display.clearDisplay();
  display.display();
}

void loop(){
customKey = customKeypad.getKey();
  switch(customKey) 
  {
  case '0' ... '9': // This keeps collecting the first value until a operator is pressed "+-*/"
    showFirst=true;
    first = first * 10 + (customKey - '0');
    showDisplay();  
    break;

  case '+':
    showFirst=false;
    Operator='+';
    showDisplay();
    second = SecondNumber(); // get the collected the second number
    total = first + second;
    showDisplay(); 
    first = total,  // reset values back to zero for next use
    second = 0;   
    break;

  case '-':
    showFirst=false;
    Operator='-';
    showDisplay();
    second = SecondNumber();
    total = first - second;
    showDisplay();
    first = total, second = 0;
    break;

  case 'x':
    showFirst=false;
    Operator='x';
    showDisplay();
    second = SecondNumber();
    total = first * second;
    showDisplay();
    first = total, second = 0;
    break;

  case '/':
    showFirst=false;
    Operator='/';
    showDisplay();
    second = SecondNumber();
    second == 0 ? display.print("Invalid") : total = (float)first / (float)second;
    showDisplay();
    first = total, second = 0;    
    break;

  case 'C':
    total = 0;
    first=0;
    second=0;
    Operator='\0';
    showFirst=false;
    equalPressed=false;
    display.clearDisplay();
    display.display();    
    break;
  }
}

void showDisplay()
{
  display.clearDisplay();
  display.setCursor(110,0);
  display.print(Operator);
  if (showFirst) {
    Serial.print(first);
    display.println(first);
  } else
  {
    display.print("");
  }
  if (second>0) {
    display.print(second);
  } else
  {
    display.print("");
  }
  if (equalPressed) {
    display.clearDisplay();
    display.setCursor(110,0);
    display.print(Operator);
    display.print(total);
    equalPressed=false;
  }
  display.display();
}
long SecondNumber()
{
  while( 1 )
  {
    customKey = customKeypad.getKey();
    if(customKey >= '0' && customKey <= '9')
    {
      second = second * 10 + (customKey - '0');
      showDisplay();
    }

    if(customKey == '=') {
      equalPressed=true;
      break;  //return second;
    }
  }
 return second; 
}

Record the keys pushed into a character array, including the decimal point. NULL terminate the array to make it a string. Use the atof() function to convert the string to a float number.

such a kind of keyboard-input is quite common. Does there exist a tutorial or a library that supports that?

best regards Stefan

i just can't get the way how to use atof()
i tried something like this in different sketch just to not make a mess

void loop() {
  
key = keypad.getKey();
String input1 = key;
double num1 atof(input1);

if (key!=NO_KEY){
  input1 = key;
  u8g2.print(input1);
  u8g2.sendBuffer();
  }
 
}

but it gives an error

Arduino: 1.8.13 (Windows 10), Board: "Arduino Nano, ATmega328P"

D:\arduino learning projects\my_calcuator_in_beta2\my_calcuator_in_beta2.ino: In function 'void loop()':

my_calcuator_in_beta2:73:17: error: conversion from 'char' to 'String' is ambiguous

 String input1 = key;

                 ^~~

In file included from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:232:0,

                 from C:\Users\Alex\Documents\Arduino\libraries\Keypad-master\src/Key.h:35,

                 from C:\Users\Alex\Documents\Arduino\libraries\Keypad-master\src/Keypad.h:36,

                 from D:\arduino learning projects\my_calcuator_in_beta2\my_calcuator_in_beta2.ino:1:

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/WString.h:61:2: note: candidate: String::String(const __FlashStringHelper*) <near match>

  String(const __FlashStringHelper *str);

  ^~~~~~

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/WString.h:61:2: note:   conversion of argument 1 would be ill-formed:

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/WString.h:59:2: note: candidate: String::String(const char*) <near match>

  String(const char *cstr = "");

  ^~~~~~

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/WString.h:59:2: note:   conversion of argument 1 would be ill-formed:

my_calcuator_in_beta2:74:13: error: expected initializer before 'atof'

 double num1 atof(input1);

             ^~~~

exit status 1

conversion from 'char' to 'String' is ambiguous



This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

A string (lowercase s) is not a String (uppercase S)

atof() works with strings

so im trying to convert char "key" to String "input" and then im not sure how to use atof but i try .

Read reply #1 carefully

Does it mention using Strings ?
Answer, no

Don't use the String class. There are other reasons besides atof() not working with String objects. See Evils of Strings

Here is my code for keypad entry of a float data type. It uses some different hardware but the keypad reading code should work without to many changes. The code records keys pressed (including decimal point) into a character array and, when entered with the # key, terminates the array to make it a string (small s) and converts the string to a float data type.

// by Charlie Goulding aka groundFungus
// Keypad number entry.  '*' key mapped as decimal point (.).
// Uses '#' key as enter key.
// 'C' to clear display and key buffer
// 'D' to delete last character from entry
// libraries:
// https://github.com/joeyoung/arduino_keypads/tree/master/Keypad_MCP
// hd44780 library available through library manager

#include <Keypad_MCP.h>
#include <Wire.h>
#include <hd44780.h>
#include <hd44780ioClass/hd44780_pinIO.h>

#define I2CADDR_KP 0x21

hd44780_pinIO lcd(2, 3, 4, 5, 6, 7);

const int LCD_COLS = 16;
const int LCD_ROWS = 2;

const byte ROWS = 4; //four rows
const byte COLS = 4; //three columns
char keys[ROWS][COLS] =
{
   {'1', '2', '3', 'A'},
   {'4', '5', '6', 'B'},
   {'7', '8', '9', 'C'},
   {'.', '0', '#', 'D'}  // # to enter numger
};
byte rowPins[ROWS] = {7, 6, 5, 4}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {3, 2, 1, 0}; //connect to the column pinouts of the keypad

char keyBuffer[22];

boolean newEntry = false;

Keypad_MCP keypad = Keypad_MCP( makeKeymap(keys), rowPins, colPins, ROWS, COLS, I2CADDR_KP );

void setup()
{
   Serial.begin(115200);
   Serial.println("MCP23008 Keypad reader");
   keypad.begin( );
   lcd.begin(LCD_COLS, LCD_ROWS);
   lcd.print("Hello, World!");
}

void loop()
{
   char key = keypad.getKey();

   if (key)
   {
      Serial.println(key);
      getEntry(key); 
   }
   if (newEntry == true)
   {
      Serial.println(entryToFloat(keyBuffer));      
      lcd.setCursor(5, 1);
      lcd.print(entryToFloat(keyBuffer));      
      newEntry = false;
   }
}

void getEntry(char key)
{
   static boolean entryStarted = false;  
   static byte keyBufferIndex = 0;
   if (key == 'C')  // if C clear buffer and display
   {
      lcd.clear();
      keyBufferIndex = 0;
      return;
   }
   if (key == 'D') // if D delete last character
   {
      if (keyBufferIndex > 0)
      {
         keyBufferIndex --;
         lcd.setCursor(keyBufferIndex, 0);
         lcd.print(' ');
         return;
      }
   }
   if (entryStarted == false)  // first character entered
   {

      keyBufferIndex = 0;
      entryStarted = true;
      keyBuffer[keyBufferIndex] = key;
      lcd.setCursor(keyBufferIndex, 0);
      lcd.print(key);
      newEntry = false;
      keyBufferIndex++;
   }
   else if (entryStarted == true && key != '#')  // if not # (enter) add key to buffer
   {
      keyBuffer[keyBufferIndex] = key;
      lcd.setCursor(keyBufferIndex, 0);
      lcd.print(key);
      keyBufferIndex++;
   }
   else if (key == '#')  // enter >> terminate array set newEntry flag
   {
      keyBuffer[keyBufferIndex] = '\0';
      entryStarted = false;
      newEntry = true;
   }
}

float entryToFloat(char* entry)  // ASCII to float
{
   return (atof(entry));
}

int entryToInt(char* entry)
{
   return (atoi(entry));
}

I'll try it . thanks!

-IF- you were ok with reverse polish calculator (Like the old HP scientific calculators) I have just the library for you!

You feed it strings that represent the button clicks then read out the X register value and display it. Done.

But many people just don't get the (Enter>Equal) thing these days.

-jim lee

RPN - happy days !

When calculators were a novelty (1970 something) someone borrowed mine and brought it back very embarrassed because they thought that they has broken it because there was a blank space in the display and the "equals" key (actually the E key, did not work

The calculator in question Sinclair Scientific - Wikipedia

my idea is just to revive the calculator with arduino and oled because the vfd is broken and im not sure if its only that that isn't okay :smiley:

@UKHeliBob Yikes what an antique.

My Dad worked for HP back in the day. He used to bring home the prototype HP calculators for us kids to "Field test". When we got the original HP 35, people who saw that would just flip out! Alien technology! :slight_smile:

@Freakmind54

VFD?

Volunteer Fire Department?
Village of Foul Devotees?

-jim lee

vfd vacuum fluorescent display

@UKHeliBob Yikes what an antique.

Indeed, and I still have it

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