String operations

Hey Guys, i have a problem that i need help with. Thanks to anyone who may like to help. Ok here is the problem.

I receive date from my solar inverter in a char array i.e.

char receivedDate[8];

This data when printed out to Serial Monitor displays as 20200105 (Thats the date for today i.e. Jan 5, 2020).

In order to send the command to get total daily energy produced from inverter i need to send the following command to the inverter.

^P013EDyyyymmdd.

the date that i extract above from the inverter is supposed to go to the yyyymmdd part.

now i store the ^P013ED part of the command as follows:

char P013ED[] = {0x5E, 0x50 ,0x30,0x31,0x33,0x45,0x44};

now i need to first convert the data stored in the receivedDate variable into HEX format and the append to the variable P013ED and followed by appending the CRC and CR to make the complete command.

can someone help me with this. I ll be very thankful.

Can you post a link to the inverter?

use sprintf() or strcpy()...

char receivedDate[8];
char P013ED[] = {0x5E, 0x50 ,0x30,0x31,0x33,0x45,0x44};
char cmd[20];
int crc;  // you will have to calculate this based on what CRC alrogithm the inverter expects

sprintf(cmd, "%s%s%d\r", P013ED, receivedDate, crc);

blh64:
use sprintf() or strcpy()...

char receivedDate[8];

char P013ED[] = {0x5E, 0x50 ,0x30,0x31,0x33,0x45,0x44};
char cmd[20];
int crc;  // you will have to calculate this based on what CRC alrogithm the inverter expects

sprintf(cmd, "%s%s%d\r", P013ED, receivedDate, crc);

Thanks. I will try this code. I ll be thankful if you can clarify a few things for me.

  1. can you help me visualize how the receivedDate is stored as compared to the P013ED variable.
  2. what would be the shape of data in cmd variable.

The actual command is a text based command i.e. ^P013EDyyyymmdd. can i send the command as follows:

Serial.write("^P013ED");//null wont be printed
Serial.write(receivedDate);
Serial.write(CRC, sizeof(CRC));
Serial.write(0x0D);

i have tried the following code and it works but the problem is that i dont know how to convert the date stored in receivedDate variable into the hex format as in the code below:

char P013ED[] = {0x5E,0x50,0x30,0x31,0x33,0x45,0x44};
char date[] = {0x32,0x30,0x32,0x30,0x30,0x31,0x30,0x35};
char CRC[] = {0x68,0x97,0x0D};

mySerial.write(P013ED, sizeof(P013ED));
  mySerial.write(date, sizeof(date)); 
  mySerial.write(CRC, sizeof(CRC));

Sorry for asking too many questions. and thanks for your help.

The inverter is an Infinisolar V 5KW.

https://voltronicpower.com/en-US/Product/Detail/InfiniSolar-V-1K-5K

thehrao:
i have tried the following code and it works but the problem is that i dont know how to convert the date stored in receivedDate variable into the hex format as in the code below:

I don't think any conversion is needed. Look up the hex numbers with this ASCII chart and you'll see they are just the representation of the alphabetic characters.

char letters[] = "ABC";
char hexletters[4]={0x41, 0x42, 0x43,0x00}; // 0x00 = terminating null

void setup() {
 Serial.begin(115200);
 Serial.println(letters);
 Serial.println(hexletters); 
}

void loop() {
 }

Thanks for the link. They want a sign up to read the manual and I declined.

dougp,

the arduino has to build the command.
part is supplied by me i.e. ^P013ED portion.
the date portion i.e. yyyymmdd is supplied by the inverter from the serial port in response to a command.
and CRC is computed by the arduino using an algorithm.

all three portions then need to be sent to inverter to get the response.

i can convert ^P013ED portion to:

char P013ED [] = {0x5E, 0x50, 0x30, 0x31,0x33, 0x45, 0x44};

and received the date part in a variable receivedDate[] which if printed to serial monitor shows up as ASCII text 20200105.
similar with the CRC.

i need to form a command that would be like this to the compiler and the arduino and the inverter

char P013ED[] = {0x5E,0x50,0x30,0x31,0x33,0x45,0x44,0x32,0x30,0x32,0x30,0x30,0x31,0x30,0x35,0x68,0x97,0x0D};

i did try the sprintf method but it didnt work or i could not make it work due to my very limited knowledge of how string works.

i ll be thankful if you can guide me.

thehrao:
i need to form a command that would be like this to the compiler and the arduino and the inverter

Refer to string.h on this page. To build a string of characters as you describe use strcat. This concatenates character arrays.

First, declare a buffer array with enough size to hold all the expected characters plus one for the terminator. Use memset to fill the buffer with terminators. This will save having to later find the end of the data.

Use strcpy to put P103ED into the buffer then use strcat to append the date to P103ED. Since your first action on the buffer was to fill it with terminators ( \0 ) the resulting string already has a terminator in place.

I've never dealt with generating or recovering CRC's so I won't offer anything in that area. There are a number of threads dealing with CRC's, just do a site search on that term.

char P013ED[] = {0x5E,0x50,0x30,0x31,0x33,0x45,0x44};
char date[] = {0x32,0x30,0x32,0x30,0x30,0x31,0x30,0x35};
char CRC[] = {0x68,0x97,0x0D};

These are arrays but they are not C strings because they lack terminating zeros.

String operations like from string.h and Serial.print() won't work right without the terminating zero.

OTOH if you were operating on chars as data and pre-knew the byte count you wouldn't need the zero.

thehrao:
The actual command is a text based command i.e. ^P013EDyyyymmdd. can i send the command as follows:

Serial.write("^P013ED");//null wont be printed

Serial.write(receivedDate);
Serial.write(CRC, sizeof(CRC));
Serial.write(0x0D);

Replace those Serial.write() calls by Serial.print() and it'll work a whole lot better. The last Serial.write() is correct.

As long as those char arrays are null terminated you should be able to Serial.print() them just fine:

char P013ED[] = {0x5E,0x50,0x30,0x31,0x33,0x45,0x44, 0x00};
char date[] = {0x32,0x30,0x32,0x30,0x30,0x31,0x30,0x35, 0x00};
char CRC[] = {0x68,0x97,0x0D, 0x00};

mySerial.print(P013ED);
mySerial.print(date); 
mySerial.print(CRC);

I highly doubt sizeof() works the way you think it works... it may return 1 (the size of the type char), maybe 2 or 4 (whatever the size of the pointer value is).

dougp,

Thanks i ll try what you suggested and get back.

dougp:
Use strcpy to put P103ED into the buffer then use strcat to append the date to P103ED.

P103ED is not terminated. strcpy() will get bytes past the end of that array until it reaches a zero.

Since your first action on the buffer was to fill it with terminators ( \0 ) the resulting string already has a terminator in place.

Too bad the resulting string won't be right. Half-right is still wrong.

GoForSmoke:
P103ED is not terminated. strcpy() will get bytes past the end of that array until it reaches a zero.

Good catch, I missed that. Could be easily corrected, though, by adding the terminator to the end of P103ED.

Using strcnpy() is another solution when not having a null terminator.

@wvmarle,

Your approach was the one i needed. adding null terminator to the Strings did the job for me.

Thank you so much.
Thank you so much all who tried to help.

Capital-S String is a different thing than lowercase-s string.

String is a C++ class object that behaves badly for small memory computing.

Get to know the language as well as the hardware, you won't need to take time waiting for answers.