How to convert char [] in to float

Hi

i have facing some problem in subtractions of two values. But i have facing the problem in this part,while running the program ,getting wrong subtraction result.

char MaintsHmr[15];/////////Last Maintenance time
char MaintsHmrSet[15];////////Current time

void loop() {

    x10 = (EEPROM.read(addr_hrs9)); //3
    x9 = (EEPROM.read(addr_hrs8)); //2
    x8 = (EEPROM.read(addr_hrs7)); //1
    x6 = (EEPROM.read(addr_hrs2));
    x7 = (EEPROM.read(addr_Minute));
    
        sprintf (MaintsHmrSet,"%1u%1u%1u%1u.%02u\n",x10,x9,x8,x6,x7);
        Serial.print("MaintsHmrSet :");
        Serial.print(MaintsHmrSet);
   
    value_hrs4   = (EEPROM.read(addr_hrs5));//3
    value_hrs3   = (EEPROM.read(addr_hrs10));//2
    value_hrs2   = (EEPROM.read(addr_hrs1));//1
    value_hrs1   = (EEPROM.read(addr_hrs3));
    value_Minute =(EEPROM.read(addr_hrs4));////Minute mats
   sprintf(MaintsHmr,"%1u%1u%1u%1u.%02u\n",value_hrs4,value_hrs3,value_hrs2,value_hrs1,value_Minute);
          Serial.print("MaintsHmr :");
          Serial.print(MaintsHmr);

float diffrRead = (MaintsHmrSet-MaintsHmr);
Serial.println(diffrRead);

}

Serial monitor shows

MaintsHmrSet :0008.12
MaintsHmr :0008.09
-15.00

Here "-15" is subtraction result.
The correct answer is 0.03 but i got it wrong. I think its because i did not change char in to float.Can anyone tell me how to correct my mistake.

atof()

Perehama:
atof()

please give me the directions for applying atof() to ma program

sreekanthmp:
please give me the directions for applying atof() to ma program

The supplied link was clickable. Did you read the web page?

sreekanthmp:
please give me the directions for applying atof() to ma program

Did you read the linked tutorial?
At the top of your program:

#include <stdlib.h>// not sure this isn't already included by one of the Arduino Core files.

then further down…

float a = atof(MaintsHmr);
float b = atof(MaintsHmrSet);
float diffrRead = (b-a);
Serial.println(diffrRead);

gfvalvo:
The supplied link was clickable. Did you read the web page?

Perehama:
atof()

Now its working

MaintsHmrSet :0008.12
MaintsHmr :0008.09
Float MaintsHmr  is :8.09
Float MaintsHmrSet  is :8.12
0.03

my thanks to you all

Why not simply save the actual float in EEPROM rather than messing around with strings and atof() when you want to read it back ?

UKHeliBob:
Why not simply save the actual float in EEPROM rather than messing around with strings and atof() when you want to read it back ?

Actually this program count the engine working hours once engine started and and its stores the the value at the time engine off. Hours stored in the form of hours and minute(0000.00).
If engine worked 255hrs.30 mts…it will store the each hours (2,5,5) in different Eeprom address and minutes in a single address (30)…
.if i store this value as “float” it will store the value in eeprom like this (0.0,2.0,5.0,5.0).So it will very difficult to do other calculation

That is 100 times more complicated than it needs to be. Just store the number of minutes in a single unsigned long integer variable. It's extremely simple to convert minutes to hours and hours to minutes - divide by 60 and multiply by 60. Integer values are much simpler and more reliable for time keeping because time is usually (and also in this case) measured in discrete units. Float variables have problems with precision and rounding (just to mention the worst, there are more). Also, it's a bad idea to store your value split up into parts - that just adds to the over complication. You only need to store a single value - after all, that is what it really is. Because hours and minutes have a fixed relationship, the only value in splitting them, is for some calculations and human display and reckoning.

aarg:
That is 100 times more complicated than it needs to be. Just store the number of minutes in a single unsigned long integer variable. It's extremely simple to convert minutes to hours and hours to minutes - divide by 60 and multiply by 60. Integer values are much simpler and more reliable for time keeping because time is usually (and also in this case) measured in discrete units. Float variables have problems with precision and rounding (just to mention the worst, there are more).

If suppose i have assigned working hours as a minutes in a unsigned long integer variable. How can i store this value in eeprom when minute crossed 255minutes as the storing the max integar value in eeprom limited
to 255

Store minutes as a uint32_t. Use 'put' and 'get' for storage and retrieval. See: https://www.arduino.cc/en/Reference/EEPROM

gfvalvo:
Store minutes as a uint32_t. Use ‘put’ and ‘get’ for storage and retrieval. See: Arduino - EEPROM

This is my engine hour meter code

#include <EEPROM.h>
#include <Wire.h>
#include <Adafruit_GFX.h>////////////////oled
#include <Adafruit_SSD1306.h>////////////oled

#include <OneWire.h>/////////////////////Temp sensor
#include <DallasTemperature.h>///////////Temp sensor
#define ONE_WIRE_BUS A0//////////////////Temp sensor
OneWire oneWire(ONE_WIRE_BUS);//////////Temp sensor
DallasTemperature sensors(&oneWire);////Temp sensor
#define ONE_WIRE_BUS A0////////////////Temp sensor

#define OLED_Address 0x3C///////////////oled
#define OLED1_Address 0x3D///////////////oled
Adafruit_SSD1306 oled(1);///////////////oled
//Adafruit_SSD1306 oled1(1);///////////////oled
//#include "Wire.h"
#define SCREEN_WIDTH 128 // ///////////////////////////////////OLED display width, in pixels
#define SCREEN_HEIGHT 64 ////////////////////////////////////////OLED
#define NUM_PAGE    8/////////////////oled

#include "RTClib.h"///////////////////// rtc
RTC_DS3231 rtc;////////////////////////// rtc
#define deviceAddress 0b1101000   //0x68

#define NUMFLAKES 10/////////////////oled
#define XPOS 0///////////////////////oled
#define YPOS 1///////////////////////oled
#define DELTAY 2///////////////////oled
#define LOGO16_GLCD_HEIGHT 16///////oled
#define LOGO16_GLCD_WIDTH  16//////oled
//Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);//OLED display height, in pixels

const uint8_t maint = 3;
const byte ledPin = 13;
const byte interruptPin = 2;
volatile byte state = LOW;
const uint8_t EngineCommand = 8;
float temp;
unsigned long time_now = 0;
unsigned long currentMillis;
unsigned long startDelay = 15000;
unsigned long waitTimeStart;

int EventState = 0;
int addr_secnd = 0;
int addr_Minute = 1;
int addr_hrs1 = 2;
int addr_hrs2 = 3;
int addr_hrs3 = 4;
int addr_hrs4 = 5;
int addr_hrs5 = 6;

int secnd = 0;
int Minute = 0;
int hrs1 = 0;
int hrs2 = 0;
int hrs3 = 0;
int hrs4 = 0;
int hrs5 = 0;
int value_secnd;
int value_Minute;
int value_hrs1;
int value_hrs2;
int value_hrs3;
int value_hrs4;
int value_hrs5;
int x6;
int x7;
int x8;


boolean waitingToStart = false ;
long lastTime = 1;
long seconds = EEPROM.read(addr_secnd);
long minutes = EEPROM.read(addr_Minute);
long hours = EEPROM.read(addr_hrs2);

void setup()
{
  oled.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  // oled1.begin(SSD1306_SWITCHCAPVCC, 0x3D);

  rtc.begin();
  sensors.begin();
  Serial.begin(9600);
  Wire.begin();
  DateTime now = rtc.now();
  if (! rtc.begin())
  {
    Serial.println("Couldn't find RTC");
    while (1);
  }
  if (rtc.lostPower())
  {
    Serial.println("RTC lost power, lets set the time!");
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }
  pinMode(ledPin, OUTPUT);
  pinMode(EngineCommand, INPUT);
  pinMode(interruptPin, INPUT_PULLUP);
  pinMode(maint, INPUT);
  attachInterrupt(digitalPinToInterrupt(interruptPin), blink, FALLING);
  setSQW(0x00);
  oled.clearDisplay();
  oled.setTextSize(2);
  oled.setTextColor(WHITE);
  oled.setCursor(0, 0);
  oled.print("Plase subscribe");
  oled.display();
  /*  oled1.setFont(&FreeMono9pt7b);
    oled1.clearDisplay();
    oled1.setTextSize(1);
    oled1.setTextColor(WHITE);
    oled1.setCursor(0, 20);
    oled1.print("SREEKANTH");
    oled1.display();*/
  delay(5000);
}

String time()
{
  String dataString = "";
  DateTime now = rtc.now();
  dataString += String(now.year(), DEC);
  dataString += String('.');
  dataString += String(now.month(), DEC);
  dataString += String('.');
  dataString += String(now.day(), DEC);

  dataString += String("    ");
  dataString += String(now.hour(), DEC);
  dataString += String(':');
  dataString += String(now.minute(), DEC);
  dataString += String(':');
  dataString += String(now.second(), DEC);
  return dataString;
}

void loop() {
  
  display1();
  
  Serial.print(hours);
  Serial.print(":");
  Serial.print(minutes);
  Serial.print(":");
  Serial.println(seconds);
  sensors.requestTemperatures();
  temp = sensors.getTempCByIndex(0);
  float sensorValue = analogRead(A1);////////////used pot.meter as pressure sensor
  if ( temp >= 24 && temp < 25  )/////////water temp sensor
  {
    oled.setTextSize(1);
    oled.setTextColor(BLACK, WHITE);
    oled.setCursor(64, 24);
    oled.print(" TEMP-HIGH  ");
    oled.display();

  }

  else if ( temp >= 26   )//////////water temp sensor
  {
    oled.setTextSize(1);
    oled.setTextColor(BLACK, WHITE);
    oled.setCursor(64, 24);
    oled.print("  ENG.OFF  ");
    oled.display();

  }
  if ( (sensorValue / 10) <= 2.00 && waitingToStart == false)////engine oil pressure
  {

    waitingToStart = true;
    unsigned long waitTimeStart = millis();
  }
  if (waitingToStart == true && (millis() - waitTimeStart ) > startDelay)
  {
    waitingToStart = false;
    oled.setTextSize(1);
    oled.setTextColor(BLACK, WHITE);
    oled.setCursor(68, 11);
    oled.print(" PRES-LOW ");
    oled.display();
  }

  digitalWrite(ledPin, HIGH);

  if (digitalRead(EngineCommand) == HIGH)/////////engine off last reading stored in eeprom
  {

    if (EventState < 1)
    {
      EEPROM.update(addr_secnd, seconds);
      EEPROM.update(addr_Minute, minutes);
      EEPROM.update(addr_hrs2, hours);
      Serial.print(EEPROM.read(addr_hrs2));
      Serial.print(EEPROM.read(addr_Minute));
      Serial.println(EEPROM.read(addr_secnd));
      EventState++;
    }
  }

}

void display1()///////////data displayed on oled
{

  
  sensors.requestTemperatures();
  temp = sensors.getTempCByIndex(0);
  float sensorValue = analogRead(A1);
  oled.clearDisplay();
  oled.setTextSize(1);
  oled.setTextColor(WHITE, BLACK);
  oled.setCursor(0, 0);
  oled.print(time());
  oled.drawLine(0, 10, 127, 10, WHITE);
  oled.drawLine(0, 11, 127, 11, WHITE);
  oled.setCursor(0, 8);
  oled.print((hours));//,":",(minutes));
  oled.print(":");
  oled.print((minutes));//,":",(minutes));
  oled.print(":");
  oled.print((seconds));//,":",(minutes));
  oled.setCursor(0, 16);
  oled.print((temp));
  oled.setCursor(0, 24);
  oled.print("E.O.P:");
  oled.print((sensorValue) / 10);

  oled.display();


}

//////////////////Engine working hours counting section///////////////////
void blink() {
  if (digitalRead(EngineCommand) == LOW)
  {

    EventState = 0;
    // if (millis() - lastTime > 0)
    //{
    if (lastTime > 0)
    {
      seconds++;

      //lastTime = millis();
    }
    if (seconds > 59)
    {

      minutes++;
      seconds = 0;

    }
    if (minutes > 59)
    {

      hours++;
      minutes = 0;
    }

    digitalWrite(ledPin, !digitalRead(ledPin));
  }

}
void setSQW(uint8_t value) {
  Wire.beginTransmission(deviceAddress); //device address and STSRT command are queued
  Wire.write(0x0E); //Control Register Address is queued
  Wire.write(0x00); //Data for Control Register is queued
  Wire.endTransmission(); //queued information are transferred under ACK; STOP
}

sreekanthmp:
If suppose i have assigned working hours as a minutes in a unsigned long integer variable. How can i store this value in eeprom when minute crossed 255minutes as the storing the max integar value in eeprom limited
to 255

I have found that when working with eeprom, it is easiest, at least for me, to create a struct of all the things I want to put in eeprom, and a function to write this struct to eeprom and a function to read this struct from eeprom. It's usually environment variables, configuration settings etc. for my applications, so I find this method helps me with the addressing. Also, in my struct is a versionNumber. And, a VersionNumber (i.e. constant, not in the struct). On boot, my program reads eeprom into RAM and compares versionNumber with VersionNumber. If they are not the same, the program sets my struct to default values and writes it to eeprom. This allows me to always update my eeprom data with the current version as my program changes.

Perehama:
I have found that when working with eeprom, it is easiest, at least for me, to create a struct of all the things I want to put in eeprom, and a function to write this struct to eeprom and a function to read this struct from eeprom. It's usually environment variables, configuration settings etc. for my applications, so I find this method helps me with the addressing. Also, in my struct is a versionNumber. And, a VersionNumber (i.e. constant, not in the struct). On boot, my program reads eeprom into RAM and compares versionNumber with VersionNumber. If they are not the same, the program sets my struct to default values and writes it to eeprom. This allows me to always update my eeprom data with the current version as my program changes.

I do the same and add on top a magic number (like 0xDEADBEEF or 0xBADCAFFE) in EEPROM.
=> If I don't see this magic number I know it's the first time I'm running on this arduino or something bad happened and my code establish default values in the struct and save them and then write the magic number.
=> if I see the magic number then I know I can trust what I read from EEPROM

J-M-L:
I do the same and add on top a magic number (like 0xDEADBEEF or 0xBADCAFFE) in EEPROM.

the versionNumber is my magic number :wink:

Perehama:
the versionNumber is my magic number :wink:

Yes that can work too if you don't have a version 0 :slight_smile:
(using multiple bytes also helps lower the probability of having the right magic number by chance - but may be you use a short cString as version like "v0.0")