Data Types, Casting, Conversion and String/Array Manipulation

I'm in the midst of trying to write a simple routine to generate lines of ASCII characters to be written via SdFat into a TXT file. This will be dummy data to test the actual code that will read the file, validate a checksum on each line and save it to FRAM. Each line will have a start and end character with ASCII representation of hex bytes.

Similar to this:
<0102030405>

Which is a representation of five bytes: 0x01 0x02 0x03 0x04 0x05

Because I need to have a valid checksum and some other things that will change from line to line, I need to do some math on the actual hex values prior to making the ASCII file.

I have two distinct problems.

  • The values are uint8 values that I need to convert to ASCII form to put in a char array so I can write to the TXT file.

  • While I work with the uint8_t hex values to calculate checksums, I can't figure out how to take a uint8_t array and put it into a char array for output to the TXT file.

So, in the big scheme of things, I can't figure out how to:

(Simplest way I can think of to explain)

Take a uint8_t array[4] = {0x01, 0x02, 0x03};

Manipulate array... array[3] = array[2] + array[1];

Convert array to ASCII. (01 02 03 05)

Concatenate the array with existing string/char array data.

And then print the string to an SD card.

In the code below, things are bit more complicated because it includes some array passing between functions. But I can't even get a basic test array to work.

Can anyone offer some ideas on how to approach this?

Thanks,

John

#define SLIP_END          0xC0
#define MDP_TOGGLE        0xff

void setup()
{
  Serial.begin(57600);
  
  char temp_arr[64];
  char temp_short_arr[3] = {0xff, 0xff};
  uint8_t k = 0x00;
  uint8_t curr_index = 0;

  // ============================================
  k = 0x00; // check formating and embedding
  sprintf(temp_arr, "%s%02x%s%x%02x", "<05", k, "05>", 0xf00f, temp_short_arr); // last %02x was just a wild stab at trying different ideas

// what I'd like to see: < 0 5 0 0 0 5 > f 0 0 f f f f f  (end of line is wrong, but not important)
  
  // print it out to see if it's right
  for(k = 0; k < 14; k++)
  {
    Serial.print(temp_arr[k]);
    Serial.print(' ');
  }
  Serial.println();
  
  // ============================================
  // Try a second approach
  curr_index = build_packet(temp_short_arr, 0);
  
  k = 0x00; // check formating and embedding
  sprintf(temp_arr, "%s%02x%s%x%02x", "<05", k, "05>", 0xf00f, temp_short_arr);
  
  // print it out to see if it's right
  for(k = 0; k < 14; k++)
  {
    Serial.print(temp_arr[k]);
    Serial.print(' ');
  }
  Serial.println();
}

void loop()
{
}


uint8_t store_a_char(char byte_to_send, char *hold_arr, uint8_t curr_index)
{
  hold_arr[curr_index] = byte_to_send / 0x10;
  curr_index++;
  hold_arr[curr_index] = byte_to_send % 0x10;
  curr_index++;
  return curr_index;
}

// This is a cut down version
// Pass a hex byte to be split into ascii repesentation bytes
uint8_t build_packet(char *hold_arr, uint8_t curr_index)
{
  curr_index = store_a_char(0xC0, hold_arr, curr_index); //no need to SLIP start and end
  return curr_index;
} 


uint8_t hex_to_int(char c){
  if(c >=97)
    c=c-32;
  int first = c / 16 - 3;
  int second = c % 16;
  int result = first*10 + second;
  if(result > 9) result--;
  return result;
}

You can put string constants right in the format string. You can't print an array just by naming it so you have to print each member of the array separately.

 char temp_arr[64];
  char temp_short_arr[3] = {0xff, 0xff};
  uint8_t k = 0x00;
  // what I'd like to see: < 0 5 0 0 0 5 > f 0 0 f f f f f
  sprintf(temp_arr, "<05%02x05>%04x%02x%02x", k, 0xf00f, temp_short_arr[0], temp_short_arr[1]);

johnwasser:
You can put string constants right in the format string.

OK, I had used an approach similar to that as a kind of bodge earlier for the k value until I stumbled across the %02x formatting element. (It's been a while since using all of the % formatting elements, so I'd forgotten all the options available.)

The problem I run into with using the individual element approach is that particular string of values will be of varying length based upon whether a value needs to be escaped. That's why I wanted a "string/array" approach. But still had me scratching my head and really knowing it wasn't possible with an unterminated array being treated as a string.

BUT! The biggest thing that hit me when I rolled over this morning was my target fixation with the concept of having to handle an entire line as a complete string for output. But I realized that print and println could solve that problem incredibly simply.

Thanks for your time looking at it and the ideas.

John