Char array conversion problems

I tried compiling this code and it refused to compile, the problem stems from the char array "myvals" in the code, i don't understand how. It gave the error message
incompatible types in assignment of 'String' to 'Char* [0]'

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <SoftwareSerial.h>
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27,16,2);
SoftwareSerial BTserial(3, 2); // RX | TX  pinMode(RVPA,OUTPUT);
void(* resetFunc) (void) = 0;
float BatVol;
float BatCap;
float ChaCur;
int Batvolref;
int VTHERM = A2; 
int VFB = A1; 
int REVPOL = A0; 
int RVPA = 5;
int REVPOL_DIG = 6;
int ARDUINO_GO = 7;
int OCP = 8;
int OTP = 9;
int PWM_O = 10;
int OVTA = 11;
int OCPA = 12;
int RevpolVolt;
int OutVolt;
int Temp;
int mindeadval = 153; 
int prowait = 500; 
int Cooloffdelay = 1000;
char s [80];
int  idx = 0;
char junk;
bool Hasrun = 0;
String inputString="";
String RECV;
char *myvals[] = {};

void loop() 
{ 
  // serial recieve code
  if (Hasrun == false){
 if (BTserial.available ()) {
        char  c = BTserial.read ();
        s [idx++] = c;
        if ('\n' == c)  {
            s [idx-1] = '\0';
            idx = 0;
            char *str;
            char *p = s;
            for (p = s; (str = strtok (p, ",")); p = NULL) {
                BTserial.print   ("Location ");
                BTserial.println (str);
                inputString += "\"";
                inputString += str;
                inputString += "\",";}
            RECV = inputString;
            BTserial.println(RECV);
            myvals = RECV;
            if (RECV != NULL){
              Hasrun = true;}
            else{Hasrun = false;}
        }
    }
  }
  else{if(Hasrun == true){
    // main loop
    
    BatVol = myvals[2].toFloat(); // Here is the problem, the error comes here
    ChaCur = myvals[3].toFloat();
    BatCap = myvals[4].toFloat();
    if (myvals[1] == "a"){
      Bavolref = (BatVol/3.7); 
    }
    else if (myvals[1] == "b"){
      Bavolref = (BatVol/3.2); 
    }
    BTserial.print(BatVol);
    BTserial.println(ChaCur);
    BTserial.println(BatCap);
    BTserial.println(Batvolref);
    BTserial.print("RevpolVolt is:");
    RevpolVolt = analogRead(REVPOL);
    BTserial.println(RevpolVolt);
    OutVolt = analogRead(VFB);
    BTserial.print("OutVolt is:");
    BTserial.println(OutVolt);
    Temp = analogRead(VTHERM);
    BTserial.print("Temp is:");
    BTserial.println(Temp);
    delay(prowait);

    // blah blah blah
    // resetFunc();
  }
  else{}
    }
}

i need to remove the string objects in myvals and turn them to floating point values and characters respectively, but i have an issue and the code doesn't compile.

No need to use Strings.

Please post examples of the input data, and explain what you want to do.

The 'C' language uses zero-terminated text strings. They contain characters in an array.
Sometimes a pointer to such a text string is used.

Suppose you create a pointer, but forget to let it point to such a text in memory. Then you could be writing memory that you don't own.

Arduino has the String object: https://www.arduino.cc/reference/en/language/variables/data-types/stringobject/.
The String object has functions to convert to and from the old fashion zero-terminated text string.

Could you add comment each time you use a old fashion text string or a pointer to it or a String object ?

this an example of the input data "a,23.5,34,56"

i don't understand :sweat_smile:

There are two types of strings. The old fashioned zero-terminated string of the 'C' language and the "String", which is something that Arduino also has.

You mix them together and then you have an array and pointers also mixed up.

Now, what do you actualy want to do with those data?

What is the point of printing each bit twice, in the following?

                BTserial.print   ("Location ");
                BTserial.println (str);
                inputString += "\"";
                inputString += str;
                inputString += "\",";}
            RECV = inputString;
            BTserial.println(RECV);

Several bugs in your program. For example

char *myvals[] = {};

How many bytes did you allocate to myvals?

myvals = RECV;

RECV is of type String. How are you going to assign a string object to a char pointer variable?
You need to use the copy function such as strcpy() from RECV.c_str() to myvals.
But your variable myvals has no place in memory, allocate a buffer for it.

nothing really it's just a test for now to verify something is working

ok, i think this is the best way to put it, i saw this arduino code https://www.arduino.cc/reference/en/language/variables/data-types/string/ , it stores multiple strings in a char array, so i want to use this part of my code:

                inputString += "\"";
                inputString += str;
                inputString += "\",";}
            RECV = inputString;

to put the data in that format, so that using this code from the link i gave,

char *myStrings[] = {"This is string 1", "This is string 2", "This is string 3",
                     "This is string 4", "This is string 5", "This is string 6"
                    };

i can store each data received in the string form as a character array

It took a bit of hacking to get your code to run but here it is, using the SafeString library SafeStringStream to supply the input from the BTserial

charArrayConversion.ino (3.7 KB)
The output is

a
,
2
3
.
5
,
3
4
,
5
6


Location a
a
Location 23.5
23.5
Location 34
34
Location 56
56
BatVol:23.50
ChaCur:34.00
BatCap:56.00
Batvolref:6
RevpolVolt is:554
OutVolt is:448
Temp is:393
BatVol:23.50
ChaCur:34.00
BatCap:56.00
Batvolref:6
RevpolVolt is:449
OutVolt is:393
 . . . 

But I don't think you need to or want to store the fields as Strings (or char [ ]) but rather just convert to floats and save those so here is another version that does that.
Here I am using SafeString functions to read and parse and convert. There are other ways of doing that like your strtok and strtod and Arduino Strings indexOf and toFloat
(See Arduino Software Solutions for other ways to read from Serial.)

BUT strtod and toFloat are very sloppy in that they just return 0.0 on error so it is difficult to tell, in general, if the the input was actually 0.0 or some other non-valid float like 'abc'
In your case you could check for 0.0 and assume an error.
In the this code I use SafeString toFloat() which returns false on errors.
charArrayConversion_Revised.ino (4.2 KB)
The output is

BatVol:23.50
ChaCur:34.00
BatCap:56.00
Batvolref:6
RevpolVolt is:523
OutVolt is:468
Temp is:373
BatVol:23.50
ChaCur:34.00
BatCap:56.00
Batvolref:6
RevpolVolt is:396
OutVolt is:400
. . . 

Wow thanks, the code works now, but i don't know how to send the BTserial data from my bluetooth chip to the safeString library, i used the software serial library to create a new serial port on the arduino, i am using the Nano so it shouldn't be really different from the Uno

Turns out i only had to change my original code and use myvals as strings in the conversion process, as opposed to characters, i got the idea from your code, i do not need to use the safestringlibrary and it saves more dynamic memory this way, here's the final code

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <SoftwareSerial.h>
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27,16,2);
SoftwareSerial BTserial(3, 2); // RX | TX  pinMode(RVPA,OUTPUT);
void(* resetFunc) (void) = 0;
float BatVol;
float BatCap;
float ChaCur;
int Batvolref;
int VTHERM = A2; 
int VFB = A1; 
int REVPOL = A0; 
int RVPA = 5;
int REVPOL_DIG = 6;
int ARDUINO_GO = 7;
int OCP = 8;
int OTP = 9;
int PWM_O = 10;
int OVTA = 11;
int OCPA = 12;
int RevpolVolt;
int OutVolt;
int Temp;
int mindeadval = 153; 
int prowait = 500; 
int Cooloffdelay = 1000;
char s [80];
int  idx = 0;
char junk;
bool Hasrun = 0;
String inputString="";
String RECV;
String myvals[4] ; // made this a string array instead of a char array
int myvals_idx = 1; // made a new dynamic integer

void loop() 
{ 
  // serial recieve code
  if (Hasrun == false){
 if (BTserial.available ()) {
        char  c = BTserial.read ();
        s [idx++] = c;
        if ('\n' == c)  {
            s [idx-1] = '\0';
            idx = 0;
            char *str;
            char *p = s;
            for (p = s; (str = strtok (p, ",")); p = NULL) {
                BTserial.print   ("Location ");
                BTserial.println (str);
                inputString += str;
            RECV = inputString;
            BTserial.println(RECV);
            myvals[myvals_idx] = RECV;
            myvals_idx++;
            inputString = "";} // clear inputString after every interation
            if (RECV != NULL){
              Hasrun = true;}
            else{Hasrun = false;}
        }
    }
  }
  else{if(Hasrun == true){
    // main loop
    
    BatVol = myvals[2].toFloat(); 
    ChaCur = myvals[3].toFloat();
    BatCap = myvals[4].toFloat();
    if (myvals[1] == "a"){
      Bavolref = (BatVol/3.7); 
    }
    else if (myvals[1] == "b"){
      Bavolref = (BatVol/3.2); 
    }
    BTserial.println(BatVol);
    BTserial.println(ChaCur);
    BTserial.println(BatCap);
    BTserial.println(Batvolref);
    BTserial.print("RevpolVolt is:");
    RevpolVolt = analogRead(REVPOL);
    BTserial.println(RevpolVolt);
    OutVolt = analogRead(VFB);
    BTserial.print("OutVolt is:");
    BTserial.println(OutVolt);
    Temp = analogRead(VTHERM);
    BTserial.print("Temp is:");
    BTserial.println(Temp);
    delay(prowait);

    // blah blah blah
    // resetFunc();
  }
  else{}
    }
}

here is the output

48.00
32.00
3.00
12
RevpolVolt is:1023
OutVolt is:1023
Temp is:0

here is the input

a,48,32,3 

It works now with not much use of memory

The define near the top of the file does the switch
#define BTserial sfStream
does the trick of switching the inputs
just comment that out to restore reading from BTserial directly

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