2

I've this array below:

dataIn[5] = 0x88;
dataIn[6] = 0x2A;
dataIn[7] = 0xC7;
dataIn[8] = 0x2B;
dataIn[9] = 0x00;
dataIn[10] = 0x28;

I need to convert those values to decimal because after that I need to convert the decimal values into ASCII and send to UART.

Eg:

|    Hexa      |      Decimal      | ASCII (I need to send this data to UART)
| 0x882AC72B00  | 584 833 248 000  | 35 38 34 38 33 33 32 34 38 30 30 30
| 0x5769345612  | 375 427 192 338  | 33 37 35 34 32 37 31 39 32 33 33 38

My problem: Those data should put all together and convert to decimal, but my compiler is just for 4 bytes and I don't know how to do this because I've 5 or more bytes ever.

Ps.: I'm using PIC18F46K80 and C18 compiler

[Edited]

Click here to see what happen when I try to use more than 4 bytes. This is my problem

Anyone could help me ?

Thanks in advance.

  • 1
    How do you group the "decimal" values? How many bits are you using for each decimal value? How do you split five bytes into four decimal values? Sorry for the repetition, and asking the same thing three times, but this is really important to help understand your problem and how to solve it. – Some programmer dude Jan 28 '18 at 18:15
  • Why do you need to send them as characters? For display? – Benjamin Barrois Jan 28 '18 at 18:24
  • Those data come from UART, so I get one by one and put into this array. "How do I group the decimal values?", I use the bitwise shifting the bits, but that is my problem, I can't do this, because my compiler is able to maximum 4 bytes. – Pedro Junior Jan 30 '18 at 00:09
  • Yeah, it's to display data, but I'll send those data to my Android app, and this app is able to "understand" just ASCII. – Pedro Junior Jan 30 '18 at 00:12

2 Answers2

0

If I have understood well, first of all you should define a union like this:

typedef union _DATA64
{
    uint64_t dataIn64;
    uint8_t dataIn8[8];
}tu_DATA64;

and then copy the hex values in the previous defined union:

uint8_t i;
tu_DATA64 data;

...

data.dataIn64=0;
for(i=0; i<5; i++)
    data.dataIn8[4-i]=dataIn[i];

now you have to convert the 64bit variable in a string using lltoa function, like suggested in this post:

char *str;

...

str=lltoa(data.dataIn64,10);

The str is the buffer string to send.

LucaG
  • 74
  • 9
  • My compiler has no "long long". My bigger variable has 4 bytes (long), that's my problem. When I'm trying to set a variable with 8 bytes and I open the debug inspect, I can see only 4 bytes because that's the maximum for my compiler. In this case, what can I do? Should I create the union as you mentioned before? – Pedro Junior Jan 30 '18 at 00:31
  • I've attached an image in my question above with example. Maybe its can help you understand better what I need. The same way, thanks for your reply – Pedro Junior Jan 30 '18 at 00:44
  • But did you tried to include `stdint.h` library and use `uint64_t` for declare variable `long long`? Usually `stdint.h` is used fot that. – LucaG Jan 30 '18 at 07:56
  • Yes, I did, but the biggest variable I have is uint32_t, xc8 compiler does not support uint64_t. That's why I don't know how handle it – Pedro Junior Jan 30 '18 at 20:35
  • 1
    Sorry for delay. I think that the only solution is to implement a custom `itoa` function that convert a byte buffer in string. You can tahke a cue from this site: [link](https://www.geeksforgeeks.org/implement-itoa/). The focus is to reimplement the moduls `num % base` and division `num/base` operation on buffer instead on int. – LucaG Feb 02 '18 at 07:42
  • Hi Lucas, no worries for your delay, your ideas are been so helpfull. I hadn't time to try to implement this solution, but when I find a solution, I'll be back here to let all of you know how to deal with. – Pedro Junior Feb 05 '18 at 10:53
0

Have you considered writing your own conversion function? Here's a working example that can be adjusted to any length.

WARNING: My C skills are not the best!

#include <stdio.h>

/******************************************************************************/

void base10_ascii(unsigned char data[], int data_size, char ans[], int ans_size) {
  char done;
  do {
    char r = 0;
    done = 1;
    for (int i=0; i<data_size; i++) {
      int b = (r<<8) + data[i]; //previous remainder and current byte
      data[i] = b / 10;
      if (data[i] > 0) done = 0; //if any digit is non-zero, not done yet
      r = b % 10;
    }
    for (int i=ans_size-1; i>0; i--) ans[i] = ans[i-1]; //bump up result
    ans[0] = r + '0'; //save next digit as ASCII (right to left)
  } while (!done);
}

/******************************************************************************/

int main(){
  char outputBuffer[15] = {0};
  char data[] = { 0x88, 0x2A, 0xC7, 0x2B, 0x00 }; //584833248000
  base10_ascii(data,sizeof data,outputBuffer,sizeof outputBuffer);
  printf("Output: %s\n",outputBuffer);
  return 0;
}
tonypdmtr
  • 3,037
  • 2
  • 17
  • 29