what is better code?

I am sending the value to serial2 every second. However, using the sprintf function will cause a break down, which affects the entire operation. I've heard that using a String is inefficient, but it does not affect the main work, so I'm using it temporarily.

How do I improve my code so that Arduino works properly?
Do I have to use a pointer?

char tempDisp[200] = "";
  sprintf(tempDisp, "%s, %d, %.2f, %.2f, %.2f, %.2f, %.2f, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %.5f, %.5f, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d \r\n", 
  TbupcLoRa1, timestamp_value, get3231Temp(), ADC_DATA_24V, ADC_DATA_12V, ADC_DATA_5V, ADC_DATA_3V, maxErrTotalCount
  , ADS1115_str[0] , ADS1115_str[1], ADS1115_str[2] , ADS1115_str[3], ADS1115_str[4] , ADS1115_str[5], ADS1115_str[6] , ADS1115_str[7]
  , FINAL_GPS_VALUE[0], FINAL_GPS_VALUE[1], LoRaParameter[0], LoRaParameter[1], LoRaParameter[2], LoRaParameter[3], LoRaParameter[4]
  , LoRaParameter[5], LoRaParameter[6], LoRaParameter[7], LoRaParameter[8], LoRaParameter[9], LoRaParameter[10]);

Serial2.println(tempDisp);
String tempDisp = "";
  tempDisp += TbupcLoRa1;          tempDisp += ", ";
  tempDisp += timestamp_value;   tempDisp += ", ";
  tempDisp += get3231Temp();      tempDisp += ", ";
  tempDisp += ADC_DATA_24V;     tempDisp += ", ";
  tempDisp += ADC_DATA_12V;     tempDisp += ", ";
  tempDisp += ADC_DATA_5V;       tempDisp += ", ";
  tempDisp += ADC_DATA_3V;       tempDisp += ", ";
  tempDisp += maxErrTotalCount;   tempDisp += ", ";
  tempDisp += ADS1115_str[0];     tempDisp += ", ";
  tempDisp += ADS1115_str[1];     tempDisp += ", ";
  tempDisp += ADS1115_str[2];     tempDisp += ", ";
  tempDisp += ADS1115_str[3];     tempDisp += ", ";
  tempDisp += ADS1115_str[4];     tempDisp += ", ";
  tempDisp += ADS1115_str[5];      tempDisp += ", ";
  tempDisp += ADS1115_str[6];      tempDisp += ", ";
  tempDisp += ADS1115_str[7];      tempDisp += ", ";
  tempDisp += FINAL_GPS_VALUE[0];tempDisp += ", ";
  tempDisp += FINAL_GPS_VALUE[1];tempDisp += ", ";
  tempDisp += LoRaParameter[0];     tempDisp += ", ";
  tempDisp += LoRaParameter[1];     tempDisp += ", ";
  tempDisp += LoRaParameter[2];     tempDisp += ", ";
  tempDisp += LoRaParameter[3];     tempDisp += ", ";
  tempDisp += LoRaParameter[4];     tempDisp += ", ";
  tempDisp += LoRaParameter[5];     tempDisp += ", ";
  tempDisp += LoRaParameter[6];     tempDisp += ", ";
  tempDisp += LoRaParameter[7];     tempDisp += ", ";
  tempDisp += LoRaParameter[8];     tempDisp += ", ";
  tempDisp += LoRaParameter[9];     tempDisp += ", ";
  tempDisp += LoRaParameter[10];
Serial2.println(tempDisp);

The float data type (%f) is not supported with sprintf on Arduino. You can use dtostrf to convert floats to strings (small s, null terminated character arrays). Then use %s to insert.

Make the Serial object do all the work...

  Serial2.print(TbupcLoRa1)
  Serial2.print(", ");
  Serial2.print(timestamp_value)
  Serial2.print(", ");
  Serial2.print(get3231Temp())
  Serial2.print(", ");
  Serial2.print(ADC_DATA_24V)
  Serial2.print(", ");
  Serial2.print(ADC_DATA_12V)
  Serial2.print(", ");
  Serial2.print(ADC_DATA_5V)
  Serial2.print(", ");
  Serial2.print(ADC_DATA_3V)
  Serial2.print(", ");
  Serial2.print(maxErrTotalCount)
  Serial2.print(", ");
  Serial2.print(ADS1115_str[0])
  Serial2.print(", ");
  Serial2.print(ADS1115_str[1])
  Serial2.print(", ");
  Serial2.print(ADS1115_str[2])
  Serial2.print(", ");
  Serial2.print(ADS1115_str[3])
  Serial2.print(", ");
  Serial2.print(ADS1115_str[4])
  Serial2.print(", ");
  Serial2.print(ADS1115_str[5])
  Serial2.print(", ");
  Serial2.print(ADS1115_str[6])
  Serial2.print(", ");
  Serial2.print(ADS1115_str[7])
  Serial2.print(", ");
  Serial2.print(FINAL_GPS_VALUE[0])
  Serial2.print(", ");
  Serial2.print(FINAL_GPS_VALUE[1])
  Serial2.print(", ");
  Serial2.print(LoRaParameter[0])
  Serial2.print(", ");
  Serial2.print(LoRaParameter[1])
  Serial2.print(", ");
  Serial2.print(LoRaParameter[2])
  Serial2.print(", ");
  Serial2.print(LoRaParameter[3])
  Serial2.print(", ");
  Serial2.print(LoRaParameter[4])
  Serial2.print(", ");
  Serial2.print(LoRaParameter[5])
  Serial2.print(", ");
  Serial2.print(LoRaParameter[6])
  Serial2.print(", ");
  Serial2.print(LoRaParameter[7])
  Serial2.print(", ");
  Serial2.print(LoRaParameter[8])
  Serial2.print(", ");
  Serial2.print(LoRaParameter[9])
  Serial2.print(", ");
  Serial2.print(LoRaParameter[10])
  Serial2.print(", ");
  Serial2.print(tempDisp);
  Serial2.println();

Thank you for answer . I tried changing it all to ‘% s’, but the main function did not work.
And I used Serial2.print several times, but the main function did not work either.
It only works when using String strings.
This function is called on a timer once a second.

The problem is in the code you didn't post.

use dtostrf to convert floats to strings

Did you do that part?

The dtostrf() function.

MorganS:
Make the Serial object do all the work...

I suspect the spaces after the commas are superfluous which allows the string constants to be eliminated saving a skosh of SRAM...

  Serial2.write(',');

I suspect the spaces after the commas are superfluous which allows the string constants to be eliminated saving a skosh of SRAM...

The compiler used by Arduino is smart enough to recognize and optimize identical strings, so all of the "Serial2.print(", ");" statements will use the same copy of the ", " string.
That also means that 25 repetitions of the same Serial.print() will end up using less RAM than a single Serial.print() of a string containing ", , , , , ..." for 25 commas, which is mildly counter-intuitive.
While there is no reason ever to concatenate the pieces of your output together before printing (just print them consecutively, as per MorganS), you might want to be aware that the compiler really wants to put function arguments into registers, so that calling any function (ie sprintf()) with more arguments than will fit into registers ends up being particularly inefficient, compared to shorter argument lists.

westfw:
...calling any function (ie sprintf()) with more arguments than will fit into registers ends up being particularly inefficient, compared to shorter argument lists.

Is there any way to know this number?

dougp:
Is there any way to know this number?

Yes, check out the avr-gcc compiler manual (the compiler's register usage is explained in the FAQ.

westfw:
[...] you might want to be aware that the compiler really wants to put function arguments into registers, so that calling any function (ie sprintf()) with more arguments than will fit into registers ends up being particularly inefficient, compared to shorter argument lists.

While this is true for normal functions, functions that use variable argument lists don't use the registers for passing the function arguments.

Viewer
Arguments to functions with variable argument lists (printf etc.) are all passed on stack, and char is extended to int.

LightuC:
Yes, check out the avr-gcc compiler manual (the compiler's register usage is explained in the FAQ.

Thanks. Karma++

As mentioned earlier, serial.print does not seem to work temporarily due to modbus time out. Checking the response time with an oscilloscope shows that the use of serial.print over string improves the overall modbus speed by 20us.

I am constantly looking for the reason why the current sprintf function breakdown occurs. It seems to be difficult to find the problem because it works with many codes.
I've learned a lot about using the serial.print and sprintf functions here.
Thank you very much all.

functions that use variable argument lists don't use the registers for passing the function arguments.

Thanks for pointing that out; I hadn't noticed it before!

C++ overloaded functions with different argument counts (but not variable number of arguments) still pass arguments in registers, though. ("Serial.print(", ");" will put the pointer in a register, even though "Serial.print(floatvar, prec)" also exists...)

westfw:
C++ overloaded functions with different argument counts (but not variable number of arguments) still pass arguments in registers, though. ("Serial.print(", ");" will put the pointer in a register, even though "Serial.print(floatvar, prec)" also exists...)

Indeed, because function overloading is not the same as using a variable argument list. Registers r25-r8 are used to pass arguments to the function, so you can have a function with the combinations shown below:

4x long/float/double + 1x any other type
9x any type except long/float/double

Keep in mind however, that if you are taking the address of an argument, the compiler has to push the argument to the stack before accessing it (This happens inside the function, the argument is still passed via the register).