Issue with STR and FLOAT

I am working on a code. Which works for 98%, only the last thing i can't find out what i am doing wrong

I have a global static char:

static char Str[20];   

With this part i return the Str

static char * dec (unsigned long long Dec) {
      sprintf(Str, "%lld", Dec);
      return Str;
}

When i run a 64 bits code.
I get this as "return Str": 7023833275277351321
That is the correct value

in a different part of the code, i would like the "Str" again.
But i needs to be a float.

This is the part i tried to change it

unsigned long long number = atol(Str);
UserVar[event->BaseVarIndex] = (number);

But this gives a response of: 2147483648 (which is wrong)

Why is the atol(Str); changing the number 7023833275277351321 to 2147483648?

What is the largest value that a long data type can hold?

from the cplusplus.com reference for strtol()
On success, the function returns the converted integral number as a long int value.

Arduino data types.

1 Like

Consider using atoll() instead.

But i needs to be a float.

What does, and why?

1 Like

That is the wrong direction of conversion.

I'm talking about this line, where atoll() is the more appropriate choice.
unsigned long long number = atol(Str);

There are no 64 bit integers mentioned in that link.

I doubt this would be neccessary, if uint64_t could be printed via sprintf.

How to Print uint64_t in Arduino

Ok. I have overlooked that strange initialization fail,
a simple constant should work, maybe a LL suffix would make the usage clearer,
the compiler should not need it.

The long data type is defined there. That was my point.

The problem is about long long ints, int64_t, that was my point.

I went to direction, because i got this error when compiling, and i didn't do the atol()
error: cannot convert 'char [20]' to 'float' in assignment

a return as long int, then this is 32 bits.
The wrong response value (2147483648) is 32bits.

Therefor changed the line

unsigned long long number = atol(Str);

to

unsigned long long number = atoll(Str);

And did test it, what response i got with this modification
It now gives me a 64bit response, but still different values
The correct value: 7023833275277351321
the value i got with attol(Str): 7023833110349350761

Have a look at a way to do the conversion.

char Str[20];

uint64_t value = 7023833275277351321;

char* dec(uint64_t n) {
  char* str = &Str[sizeof(Str) - 1];
  *str = '\0';
  do {
    char c = n % 10;
    n /= 10;
    *--str = c + '0';
  } while (n > 0);
  return str;
}

void setup() {
  Serial.begin(115200);
  Serial.print(F("conversion returns '"));
  Serial.print(dec(value));
  Serial.println(F("'"));
}
void loop() {}
conversion returns '7023833275277351321'

In the process of testing this, I verified that the %lld format in sprintf does not produce output,
on an Arduino Nano.

I don't get it with the part you posted

You return to Str.
But Str has a value, which i want to use. But converting it goes wrong

This is char Str[20], not the uint64
char Str[20] = 7023833275277351321;

When i got it right, the "char Str[20] has to be converted to uint64?

Your function

tries to convert a binary uint64_t to a string representation in base 10, and fails on 8 bit Arduinos.

My code works.

If you want a different type of conversion, maybe your snippet should have been different?

And please post a complete sketch, not unrelated snippets.

This is the complete sketch

The challenge i have is on line 203, where the wrong value is given.
The "return Str" on lines 331-335 is working and gives me to correct value back.

Some lines could be that you think: what has he done there.
It is hobby and still learning about things

#include "_Plugin_Helper.h"
#include <RCSwitch64.h>  

static RCSwitch64 Plugin_144_RC = RCSwitch64();
char Str[20];      

#define PLUGIN_144
#define PLUGIN_ID_144         144
#define PLUGIN_NAME_144       "RC-Switch TX"
#define PLUGIN_ValueNAME1_144 "RF"

boolean Plugin_144(byte function, struct EventStruct *event, String& string)
{
  boolean success = false;
  
  switch (function)
  {
    case PLUGIN_DEVICE_ADD:
      {
        Device[++deviceCount].Number = PLUGIN_ID_144;
        //Device[deviceCount].Type = DEVICE_TYPE_DUAL;
        Device[deviceCount].Ports = 0;
        Device[deviceCount].VType = Sensor_VType::SENSOR_TYPE_DUAL;
        Device[deviceCount].PullUpOption = false;
        Device[deviceCount].InverseLogicOption = false;
        Device[deviceCount].FormulaOption = false;
        Device[deviceCount].ValueCount = 1;
        Device[deviceCount].SendDataOption = true;
        Device[deviceCount].TimerOption = false;
        Device[deviceCount].TimerOptional = false;
        Device[deviceCount].GlobalSyncOption = true;
        break;
      }

    case PLUGIN_GET_DEVICENAME:
      {
        string = F(PLUGIN_NAME_144);
        break;
      }

    case PLUGIN_GET_DEVICEVALUENAMES:
      {
        strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_ValueNAME1_144));
        break;
      }

    case PLUGIN_WEBFORM_LOAD:
      {  
        addFormPinSelect(F("TX-GPIO"),  F("taskdevicepin1"), CONFIG_PIN1);
        addFormPinSelect(F("RX-GPIO"),  F("taskdevicepin2"), CONFIG_PIN2);
//      addFormCheckBox(F("Use transceiver"), F("transceiver"), PCONFIG(1));    //future work
        addFormPinSelect(F("Enable-GPIO"),  F("taskdevicepin3"), CONFIG_PIN3);
        addFormPinSelect(F("TX_RX Toggle-GPIO"),  F("taskdevicetxpin"), PCONFIG(2));
        
        success = true;
        break;
      }

    case PLUGIN_WEBFORM_SAVE:
      {
//        PCONFIG(1)       = isFormItemChecked(F("transceiver"));    //future work
        PCONFIG(2)       = getFormItemInt(F("taskdevicetxpin"));
        success = true;
        break;
      }

    case PLUGIN_INIT:
      {
        if (CONFIG_PIN1 >= 0) //TX-pin
        {
          pinMode(CONFIG_PIN1, OUTPUT);
          String log = F("RC-Sw: Send Pin ");
          log += CONFIG_PIN1;
          log += F(" ");

          Plugin_144_RC.enableTransmit(CONFIG_PIN1);

          addLog(LOG_LEVEL_INFO, log);
        }

        if (CONFIG_PIN2 >= 0) // RX-pin
        {
          pinMode(CONFIG_PIN2, INPUT_PULLUP);
          String log = F("RC-Sw: Receive pin ");
          log += CONFIG_PIN2;
          log += F(" ");

          Plugin_144_RC.enableReceive(CONFIG_PIN2);

          addLog(LOG_LEVEL_INFO, log);
        }

        if (CONFIG_PIN3 >= 0)  //enable pin
          pinMode(CONFIG_PIN3, OUTPUT);
        if (PCONFIG(2) >= 0)  //TX_RX pin
          pinMode(PCONFIG(2), OUTPUT);  
        

        //Prefix Enable and TX_RX pin to low
        digitalWrite (CONFIG_PIN3, LOW);
        digitalWrite (PCONFIG(2), LOW);
        delayMicroseconds(500);


        //Set transceiver to RX after powerdown
        digitalWrite (CONFIG_PIN3, HIGH);
        delayMicroseconds(20);
        digitalWrite (PCONFIG(2), HIGH);
        delayMicroseconds(200);
        digitalWrite (PCONFIG(2), LOW);
        delayMicroseconds(40);
        digitalWrite (CONFIG_PIN3, LOW);
        delayMicroseconds(20);
        digitalWrite (CONFIG_PIN3, HIGH);
        delayMicroseconds(200);

        success = true;
        break;
      }

      case PLUGIN_ONCE_A_SECOND:
        {
          if (CONFIG_PIN2 >= 0) {
            if (UserVar[event->BaseVarIndex] != 0) {
              UserVar[event->BaseVarIndex] = (0);
            }
            
            if (Plugin_144_RC.available())
              {
                Serial.print("RF recieved");
                int valuerf = Plugin_144_RC.getReceivedValue();

                if (valuerf == 0) {
                  String log = F("RFcode: ");
                  log += String(valuerf);
                  log += " =Unknown encoding";
                  addLog(LOG_LEVEL_INFO, log);
        
                } else {

                   int databuffer[128]; // get a copy of the received timings before they are overwritten
                   int numberoftimings = 2 * Plugin_144_RC.getReceivedBitlength() + 2;
                   if(numberoftimings > 128) numberoftimings = 128;
                   for (int i = 0; i < numberoftimings; i++) {
                     databuffer[i] = Plugin_144_RC.getReceivedRawdata()[i];
                   }

                   String printEmpty = F("");
                   addLog(LOG_LEVEL_INFO, printEmpty);

                   String printSerial1 = F("RFcode: ");
                   printSerial1 += F("Protocol: ");
                   printSerial1 += ( Plugin_144_RC.getReceivedProtocol() );
                   printSerial1 += F(", ");
                   printSerial1 += ( Plugin_144_RC.getReceivedBitlength() );
                   printSerial1 += F(" bit");
                   addLog(LOG_LEVEL_INFO, printSerial1);
                   
                   unsigned int databitsoffset = abs( (int)Plugin_144_RC.getReceivedLevelInFirstTiming() - (int)Plugin_144_RC.getReceivedInverted());
                   
                   unsigned long dataduration = 0;
                   for (unsigned int i = 1 + databitsoffset; i < numberoftimings - 1 + databitsoffset; i++) {
                     dataduration += databuffer[i];
                   }
                   String printSerial2 = F("RFcode: ");
                   printSerial2 += F("Data bits of pulse train duration: ");
                   printSerial2 += ( dataduration );
                   addLog(LOG_LEVEL_INFO, printSerial2);

                   unsigned int averagebitduration = (int)(0.5 + ((double)dataduration)/Plugin_144_RC.getReceivedBitlength());
                   unsigned int protocolratio = (unsigned int)(0.5 + ((double)(averagebitduration - Plugin_144_RC.getReceivedDelay())) / (double)Plugin_144_RC.getReceivedDelay());
                   String printSerial3 = F("RFcode: ");
                   printSerial3 += F("Proposed protocol: { ");
                   printSerial3 += (Plugin_144_RC.getReceivedDelay());
                   printSerial3 += F(", { ");
                   printSerial3 += ( (databitsoffset==0) ? 
                   (int) (0.5 + (double)databuffer[2*Plugin_144_RC.getReceivedBitlength()+1]/(double)Plugin_144_RC.getReceivedDelay())
                   :
                   (int) (0.5 + (double)databuffer[0]/(double)Plugin_144_RC.getReceivedDelay())
                   );
                   printSerial3 += F(", ");
                   printSerial3 += ( (databitsoffset==0) ?
                   (int) (0.5 + (double)databuffer[0]/(double)Plugin_144_RC.getReceivedDelay())
                   :
                   (int) (0.5 + (double)databuffer[1]/(double)Plugin_144_RC.getReceivedDelay())
                   );
                   printSerial3 += F(" }, { ");
                   printSerial3 += F("1");
                   printSerial3 += F(", ");
                   printSerial3 += (protocolratio);
                   printSerial3 += F(" }, { ");
                   printSerial3 += (protocolratio);
                   printSerial3 += F(", ");
                   printSerial3 += F("1");
                   printSerial3 += F(" }, ");
                   printSerial3 += ((Plugin_144_RC.getReceivedInverted()) ? "true" : "false" );
                   printSerial3 += F(" }");
                   addLog(LOG_LEVEL_INFO, printSerial3);

                   binair(Plugin_144_RC.getReceivedValue(), Plugin_144_RC.getReceivedBitlength());

                   uint64_t number = atoll(Str);
                   UserVar[event->BaseVarIndex] = (number);
                   sendData(event);

                }

              Plugin_144_RC.resetAvailable();
            }
            success = true;
            break;
          }
        }
  
    case PLUGIN_WRITE:
      {
        if (PCONFIG(2) >= 0) {
          String command = parseString(string, 1);

          if (command == F("rc")) {
            String param;
            byte paramIdx = 2;

            string.replace("  ", " ");
            string.replace(" =", "=");
            string.replace("= ", "=");

            param = parseString(string, paramIdx++);
            while (param.length()) {
              addLog(LOG_LEVEL_DEBUG_MORE, param);

              int index = param.indexOf('=');
              if (index > 0) {
                String paramKey = param.substring(0, index);
                String paramVal = param.substring(index+1);
                paramKey.toUpperCase();

                addLog(LOG_LEVEL_DEBUG_MORE, paramKey);
                addLog(LOG_LEVEL_DEBUG_MORE, paramVal);

                if (paramKey == F("SEND")) {
                  if (paramVal.indexOf("F") >= 0)
                    Plugin_144_RC.sendTriState(&(paramVal[0]));
                  else
                    Plugin_144_RC.send(&(paramVal[0]));
                }
                if (paramKey == F("ON")) {
                  if (paramVal.length()==10)   //simple 10 DIP switch
                    Plugin_144_RC.switchOn(&(paramVal.substring(0, 5)[0]), &(paramVal.substring(5)[0]));
                  else if (paramVal.length()==2)   //2x rotary switch 1..4
                    Plugin_144_RC.switchOn(paramVal[0]-'0', paramVal[1]-'0');
                  else if (paramVal.length()==3)   //Intertechno outlets
                    Plugin_144_RC.switchOn(paramVal[0], paramVal[1]-'0', paramVal[2]-'0');
                }
                if (paramKey == F("OFF")) {
                  if (paramVal.length()==10)   //simple 10 DIP switch
                    Plugin_144_RC.switchOff(&(paramVal.substring(0, 5)[0]), &(paramVal.substring(5)[0]));
                  else if (paramVal.length()==2)   //2x rotary switch 1..4
                    Plugin_144_RC.switchOff(paramVal[0]-'0', paramVal[1]-'0');
                  else if (paramVal.length()==3)   //Intertechno outlets
                    Plugin_144_RC.switchOn(paramVal[0], paramVal[1]-'0', paramVal[2]-'0');
                }
                if (paramKey == F("PROTOCOL")) {
                  Plugin_144_RC.setProtocol(paramVal.toInt());
                }
                if (paramKey == F("PULSE")) {
                  Plugin_144_RC.setPulseLength(paramVal.toInt());
                }
                if (paramKey == F("REPEAT")) {
                  Plugin_144_RC.setRepeatTransmit(paramVal.toInt());
                }
              }

              param = parseString(string, paramIdx++);
            }

            success = true;
          }

          break;
        }
      }

    case PLUGIN_READ:
      {
        //no values
        success = true;
        break;
      }

  }
  return success;
}

/* extended logging, for in terminal monitor */
static char * dec2binWzerofill(unsigned long long Dec, unsigned int bitLength);
static char * dec(unsigned long long Dec);

void binair(unsigned long long decimal, unsigned int length) {
      if (decimal == 0) {
        Serial.print("Unknown encoding.");
      } else {
        const char* b = dec2binWzerofill(decimal, length);

        String printBinary = F("RFcode: ");              
        printBinary += F("Binary: "); 
        printBinary += b;
        addLog(LOG_LEVEL_INFO, printBinary);

        String printDecimal = F("RFcode: ");
        printDecimal += F("Decimal: ");
        const char* d = dec(decimal);
        printDecimal += d;
        addLog(LOG_LEVEL_INFO, printDecimal);
 
        String url = String(NetworkLocalIP().toString()) + "/control?cmd=RC";
        String printString = F("RFcode: http://");
        printString += url;
        printString += F(",PROTOCOL=");
        printString += ( Plugin_144_RC.getReceivedProtocol() );
        printString += F(",SEND=");
        printString += b;
        printString += F("");
        addLog(LOG_LEVEL_INFO, printString);

        String printEmpty = F("");
        addLog(LOG_LEVEL_INFO, printEmpty);
      }
}

static char * dec (unsigned long long Dec) {
      static char Str[20];      
      sprintf(Str, "%lld", Dec);
      return Str;
}

static char * dec2binWzerofill(unsigned long long Dec, unsigned int bitLength) {

        static char bin[128];
        unsigned int i=0;

        while (Dec > 0) {
                bin[64+i++] = ((Dec & 1) > 0) ? '1' : '0';
                Dec = Dec >> 1;
        }

        for (unsigned int j = 0; j< bitLength; j++) {
                if (j >= bitLength - i) {
                        bin[j] = bin[ 63 + i - (j - (bitLength - i)) ];
                } else {
                        bin[j] = '0';
                }
        }
        bin[bitLength] = '\0';
        
        return bin;
}

It's a f-ing conversion, :upside_down_face:
please create a minimal example that shows the problem,
as a compilable complete sketch.

What type of Arduino are you using?

Instead of:

char Str[20] = 7023833275277351321;

try

char Str[20] = "7023833275277351321";

We really have no idea what you are doing, because you don't post complete, readable code.

Therefore, post a complete, minimal example that will compile, run and demonstrate the problem.

You want to convert from char to uint64_t, that is even simpler than the other way around.

char txt[] = "7023833275277351321";

char* dec(uint64_t n);
uint64_t cvttoull(const char *res);

void setup() {
  Serial.begin(115200);
  Serial.print(F("conversion from '"));
  Serial.print(txt);
  Serial.print(F("' results in "));
  uint64_t val = cvttoull(txt);
  Serial.print(dec(val));
  Serial.println();
}
void loop() {}

uint64_t cvttoull(const char *res) {
  uint64_t result = 0;
  while (*res) {
    result *= 10;
    result += *res++ - '0';
  }
  return result;
}

char* dec(uint64_t n) {
  static char Str[20];
  char* str = &Str[sizeof(Str) - 1];
  *str = '\0';
  do {
    char c = n % 10;
    n /= 10;
    *--str = c + '0';
  } while (n > 0);
  return str;
}
conversion from '7023833275277351321' results in 7023833275277351321

This is part of a bigger sketch.
It is a plugin sketch for espeasy

The part i posted is the complete plugin part.
The rest is used from the espeasy sketch

You don't listen, good luck with your project.