2

I'm working with a PIC microprocessor, and I need to send values from an AD-Converter to a terminal (in this case HyperTerminal). Now, the terminal only understands ASCII. The value the AD-Converter gives a single byte (so ranging from 0 to 255). How can convert this binary number to ASCII?

To be entirely clear, the byte is binary. So 0100 0000 should result in 64. Ofcourse this would mean needing to send 2 ASCII numbers to the pc.

Edit: Apparently I'm not entirely clear here. I need to have the ASCII-code of the binary number in binary as well so I can send it through a USB-template provided by the chip-manufacturer.

Edit 2: After some more delving into other topics, this answer led me to trying out itoa() and utoa(). Now, itoa() works, but unfortunately is for unsigned charachters. utoa() would be for unsigned chars, but that doesn't work. Here's an example of what should be able to happen:

char USB_In_Buffer[64];
char myValue = 0x55;

itoa(myValue, USB_In_Buffer);
putUSBUSART(USB_In_Buffer, 3);

So every ASCII character should be sent to USB_In_Buffer. Then the total of characters written to this buffer should be used as second parameter in putUSBUSART(). I only need to convert numbers to ASCII as well, so not the whole characterset needs to be implemented.

Edit 3: Because some automated functions do not appear to be supported, I thought it wouldn't be that hard to make my own function.

if(ADCONvalue/100 != 0){
    res++;
    USB_In_Buffer[0] = (ADCONvalue / 100) + 0x30;
}
if(ADCONvalue/10 != 0){
    res++;
    if(res == 1){
        USB_In_Buffer[0] = (ADCONvalue / 10) + 0x30;
    }else{
        USB_In_Buffer[1] = (ADCONvalue / 10) + 0x30;
    }   

}
res++;
if(res == 1){
    USB_In_Buffer[0] = ADCONvalue % 10 + 0x30;
}else if(res == 2){
    USB_In_Buffer[1] = ADCONvalue % 10 + 0x30;
}else{
    USB_In_Buffer[2] = ADCONvalue % 10 + 0x30;
}
putUSBUSART(USB_In_Buffer, res);

But there seems to be an error somewhere. Small numbers do work (0-99), but for some reason when there should be 121, it displays 1<1. For larger numbers, all the chars are non-numeric.

Edit 4: After rechecking my code I found the error. For one, ADCONvalue was a char, not an unsigned char. Also I forgot to do %10 for the tenths. Current working code:

if(ADCONvalue/100 != 0){
    res++;
    USB_In_Buffer[0] = (ADCONvalue / 100) + 0x30;
}
if(ADCONvalue/10 != 0){
    res++;
    if(res == 1){
        USB_In_Buffer[0] = (ADCONvalue / 10)%10 + 0x30;
    }else{
        USB_In_Buffer[1] = (ADCONvalue / 10)%10 + 0x30;
    }   

}
res++;
if(res == 1){
    USB_In_Buffer[0] = ADCONvalue % 10 + 0x30;
}else if(res == 2){
    USB_In_Buffer[1] = ADCONvalue % 10 + 0x30;
}else{
    USB_In_Buffer[2] = ADCONvalue % 10 + 0x30;
}
putUSBUSART(USB_In_Buffer, res);
Community
  • 1
  • 1
jdepypere
  • 3,453
  • 6
  • 54
  • 84
  • Just so you know: HyperTerminal doesn't use ASCII; It uses the user-default code page (e.g., Windows-1252). Of course, any character set you are likely to use is a superset of ASCII with identical (8-bit) encodings for the shared characters. – Tom Blodget Dec 08 '13 at 03:47

4 Answers4

4

Build an IntToHex() helper function.

static char IntToHex(unsigned x) {
  x &= 15;
  if (x <= 9) return x + '0';
  return x - 10 + 'A';
  }

unsigned char ADConverter;
char s[3];
s[0] = IntToHex(ADConverter >> 4);
s[1] = IntToHex(ADConverter);
s[2] = '\0';
send(s);

For the reverse see hexadecimal ASCII chars conversion

Community
  • 1
  • 1
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
3

You might like to look at the printf() family of functions.

char str[32] = "";
unsigned char byte = 42;
snprintf(str, sizeof(str), "%hhu", byte); 
printf("'%s'", str); /* This is a debug statement to check what's be placed in str. */

prints out

'42'

Update referring the "send" function mentioned in the OP's update:

After having converted the integer vlaue of byte to its alphanumerical representation using snprintf() above, it could be place in the send buffer doing so:

putUSBUSART(str, strlen(str));
alk
  • 69,737
  • 10
  • 105
  • 255
  • 1
    Please prefer `snprintf()` if available. –  Dec 07 '13 at 18:21
  • 1
    I would wonder if `printf` family is even available on his micro-controller. – Bert Dec 07 '13 at 18:21
  • But doesn't `printf` and `snprintf` write something on a terminal? I need to send it through USB to the pc, so I cant just print something. – jdepypere Dec 07 '13 at 19:08
  • @Bert `printf()` and family is typically available with PICs. The extent of the parts, and its size, that may be incorporated sometimes depends on the fixed format parameter strings. It is a bit expensive in code space for the whole package. – chux - Reinstate Monica Dec 08 '13 at 01:31
  • Apparantly using `sprintf()` , even though I'm including ``, isn't supported in my compiler/device. – jdepypere Dec 08 '13 at 11:03
2

Here's a way to break down an unsigned char into decimal by dividing by 100, 10, and then using the remainder:

#include <stdio.h>

int main (void) {
   unsigned char val = 137;
   unsigned char res;

   printf("\n\nHundredths: %u\n", (int)((val / 100)));
   val = val % 100;
   printf("Tenths:     %u\n", (int)val / 10);
   printf("Ones:       %u\n", (int)val % 10);

   return 0;
}

The program outputs:

Hundredths: 1
Tenths:     3
Ones:       7

To convert to ASCII you ave to add 48 to each integer value. The ASCII codes for each of those numbers would be 49, 51, and 55.

Bert
  • 2,134
  • 19
  • 19
1

A general purpose function for converting from a signed short binary value to a text string as decimal digits is provided below along with a companion function to convert an unsigned short binary value to a text string as hex digits.

I think if you change the short to long and the unsigned short to unsigned long the same logic would convert a signed long binary value to decimal digit text and an unsigned long binary value to hex digit text respectively.

/*
 *   char *ShortToString (short sVal, char *pOutText, int iLen)
 *
 *   Input:    sVal      - binary value as a signed short to convert to text
 *             pOutText  - pointer to a character array to receive the text
 *             iLen      - length of the character array in characters
 *
 *   Returns:  char * - saved value of pOutText, pointer to beginning of output buffer
 *
 *   Description:  Converts the signed binary value of sVal into a text string of decimal digits.
 *                 If the value of sVal is negative, a minus sign is the first character.
 *                 If the output buffer length is too small, astericks are put into the buffer.
 *
 *                 WARNING: Buffer must be sized to include a terminating zero for the end
 *                          of string character.
**/
char *ShortToString (short sVal, char *pOutText, int iLen)
{
    char *pOutTextSave = pOutText;
    char *pOutTextBegin = pOutText;

    if (sVal < 0) {
        sVal *= -1;
        *pOutText++ = '-';
    }
    pOutTextBegin = pOutText;    // remember where beginning of numeric string is

    // generate text digits in order from least significant to most significant
    do {
        *pOutText++ = (sVal % 10) + '0';  // convert least signicant decimal digit to text character
        sVal /= 10;                       // shift the binary value one decimal digit righ
    } while (sVal > 0 && pOutText + 1 < pOutTextSave + iLen);

    *pOutText = 0;   // end of string terminator
    pOutText--;      // back up one to point to last character.

    if (sVal) {
        // if there is insufficient room in the provided buffer for the string of digits
        // then indicate by filling the buffer with astericks.
        pOutTextBegin = pOutTextSave;
        while (pOutTextBegin + 1 < pOutTextSave + iLen) {*pOutTextBegin++ = '*'; }
        *pOutTextBegin = 0;   // end of string terminator
    } else {
        // reverse the string so that digits are in the right order,
        // most significant to least significant. we do this by swapping digits
        // until we come to the middle which means that everything is in order.
        while (pOutTextBegin < pOutText) {
            char k = *pOutTextBegin;
            *pOutTextBegin = *pOutText;
            *pOutText = k;
            pOutTextBegin++; pOutText--;
        }
    }

    return pOutTextSave;
}

/*
 *   char *HexShortToString (unsigned short usVal, char *pOutText, int iLen)
 *
 *   Input:    usVal     - binary value as an unsigned short to convert to text
 *             pOutText  - pointer to a character array to receive the text
 *             iLen      - length of the character array in characters
 *
 *   Returns:  char * - saved value of pOutText, pointer to beginning of output buffer
 *
 *   Description:  Converts the unsigned binary value of sVal into a text string of hex digits.
 *                 If the output buffer length is too small, astericks are put into the buffer.
 *
 *                 WARNING: Buffer must be sized to include a terminating zero for the end
 *                          of string character.
**/
char *HexShortToString (unsigned short usVal, char *pOutText, int iLen)
{
    char *pOutTextSave = pOutText;

    // generate text digits in order from least significant to most significant
    do {
        unsigned char uChar = usVal & 0x000f;

        *pOutText++ = (uChar < 10) ? uChar + '0' : uChar - 10 + 'A';  // convert least signicant hex digit to text character
        usVal >>= 4;                       // shift the binary value one hex digit righ
    } while (usVal > 0 && pOutText + 1 < pOutTextSave + iLen);

    *pOutText = 0;   // end of string terminator
    pOutText--;      // back up one to point to last character.

    if (usVal) {
        // if there is insufficient room in the provided buffer for the string of digits
        // then indicate by filling the buffer with astericks.
        pOutText = pOutTextSave;
        while (pOutText + 1 < pOutTextSave + iLen) {*pOutText++ = '*'; }
        *pOutText = 0;   // end of string terminator
    } else {
        char *pOutTextBegin = pOutTextSave;

        // reverse the string so that digits are in the right order,
        // most significant to least significant. we do this by swapping digits
        // until we come to the middle which means that everything is in order.
        while (pOutTextBegin < pOutText) {
            char k = *pOutTextBegin;
            *pOutTextBegin = *pOutText;
            *pOutText = k;
            pOutTextBegin++; pOutText--;
        }
    }

    return pOutTextSave;
}

A simple test harness is as follows.

int main(int argc, char **argv)
{
    char pOutBuff[16], pOutBuffHex[16];
    char *p, *pHex;
    short sVal, sLen;

    p = ShortToString((sVal = 0), pOutBuff, (sLen = 15));
    pHex = HexShortToString(sVal, pOutBuffHex, sLen);
    printf (" sVal = %d  ShortToString() p = %s, 0x%x pHex=%s len = %d\n", sVal, p, sVal, pHex, sLen);
    p = ShortToString((sVal = 0), pOutBuff, (sLen = 2));
    printf (" sVal = %d  ShortToString() p = %s len = %d\n", sVal, p, sLen);
    p = ShortToString((sVal = 1), pOutBuff, (sLen = 15));
    pHex = HexShortToString(sVal, pOutBuffHex, sLen);
    printf (" sVal = %d  ShortToString() p = %s, 0x%x pHex=%s len = %d\n", sVal, p, sVal, pHex, sLen);
    p = ShortToString((sVal = -1), pOutBuff, (sLen = 15));
    pHex = HexShortToString(sVal, pOutBuffHex, sLen);
    printf (" sVal = %d  ShortToString() p = %s, 0x%x pHex=%s len = %d\n", sVal, p, sVal, pHex, sLen);
    p = ShortToString((sVal = 12), pOutBuff, (sLen = 15));
    pHex = HexShortToString(sVal, pOutBuffHex, sLen);
    printf (" sVal = %d  ShortToString() p = %s, 0x%x pHex=%s len = %d\n", sVal, p, sVal, pHex, sLen);
    p = ShortToString((sVal = -12), pOutBuff, (sLen = 15));
    pHex = HexShortToString(sVal, pOutBuffHex, sLen);
    printf (" sVal = %d  ShortToString() p = %s, 0x%x pHex=%s len = %d\n", sVal, p, sVal, pHex, sLen);
    p = ShortToString((sVal = 12), pOutBuff, (sLen = 2));
    pHex = HexShortToString(sVal, pOutBuffHex, sLen);
    printf ("     sVal = %d  ShortToString() p = %s, 0x%x pHex=%s len = %d\n", sVal, p, sVal, pHex, sLen);
    p = ShortToString((sVal = -12), pOutBuff, (sLen = 2));
    pHex = HexShortToString(sVal, pOutBuffHex, sLen);
    printf ("     sVal = %d  ShortToString() p = %s, 0x%x pHex=%s len = %d\n", sVal, p, sVal, pHex, sLen);
    p = ShortToString((sVal = 12), pOutBuff, (sLen = 3));
    pHex = HexShortToString(sVal, pOutBuffHex, sLen);
    printf ("     sVal = %d  ShortToString() p = %s, 0x%x pHex=%s len = %d\n", sVal, p, sVal, pHex, sLen);
    p = ShortToString((sVal = -12), pOutBuff, (sLen = 3));
    pHex = HexShortToString(sVal, pOutBuffHex, sLen);
    printf ("     sVal = %d  ShortToString() p = %s, 0x%x pHex=%s len = %d\n", sVal, p, sVal, pHex, sLen);
    p = ShortToString((sVal = 12), pOutBuff, (sLen = 4));
    pHex = HexShortToString(sVal, pOutBuffHex, sLen);
    printf ("     sVal = %d  ShortToString() p = %s, 0x%x pHex=%s len = %d\n", sVal, p, sVal, pHex, sLen);
    p = ShortToString((sVal = -12), pOutBuff, (sLen = 4));
    pHex = HexShortToString(sVal, pOutBuffHex, sLen);
    printf ("     sVal = %d  ShortToString() p = %s, 0x%x pHex=%s len = %d\n", sVal, p, sVal, pHex, sLen);
    p = ShortToString((sVal = -12), pOutBuff, (sLen = 5));
    pHex = HexShortToString(sVal, pOutBuffHex, sLen);
    printf ("     sVal = %d  ShortToString() p = %s, 0x%x pHex=%s len = %d\n", sVal, p, sVal, pHex, sLen);
    p = ShortToString((sVal = 103), pOutBuff, (sLen = 15));
    pHex = HexShortToString(sVal, pOutBuffHex, sLen);
    printf (" sVal = %d  ShortToString() p = %s, 0x%x pHex=%s len = %d\n", sVal, p, sVal, pHex, sLen);
    p = ShortToString((sVal = -103), pOutBuff, (sLen = 15));
    pHex = HexShortToString(sVal, pOutBuffHex, sLen);
    printf (" sVal = %d  ShortToString() p = %s, 0x%x pHex=%s len = %d\n", sVal, p, sVal, pHex, sLen);
    p = ShortToString((sVal = 100), pOutBuff, (sLen = 15));
    pHex = HexShortToString(sVal, pOutBuffHex, sLen);
    printf (" sVal = %d  ShortToString() p = %s, 0x%x pHex=%s len = %d\n", sVal, p, sVal, pHex, sLen);
    p = ShortToString((sVal = -100), pOutBuff, (sLen = 15));
    pHex = HexShortToString(sVal, pOutBuffHex, sLen);
    printf (" sVal = %d  ShortToString() p = %s, 0x%x pHex=%s len = %d\n", sVal, p, sVal, pHex, sLen);
    p = ShortToString((sVal = 123), pOutBuff, (sLen = 15));
    pHex = HexShortToString(sVal, pOutBuffHex, sLen);
    printf (" sVal = %d  ShortToString() p = %s, 0x%x pHex=%s len = %d\n", sVal, p, sVal, pHex, sLen);
    p = ShortToString((sVal = -123), pOutBuff, (sLen = 15));
    pHex = HexShortToString(sVal, pOutBuffHex, sLen);
    printf (" sVal = %d  ShortToString() p = %s, 0x%x pHex=%s len = %d\n", sVal, p, sVal, pHex, sLen);
    p = ShortToString((sVal = 1234), pOutBuff, (sLen = 15));
    pHex = HexShortToString(sVal, pOutBuffHex, sLen);
    printf (" sVal = %d  ShortToString() p = %s, 0x%x pHex=%s len = %d\n", sVal, p, sVal, pHex, sLen);
    p = ShortToString((sVal = -1234), pOutBuff, (sLen = 15));
    pHex = HexShortToString(sVal, pOutBuffHex, sLen);
    printf (" sVal = %d  ShortToString() p = %s, 0x%x pHex=%s len = %d\n", sVal, p, sVal, pHex, sLen);
    p = ShortToString((sVal = 12345), pOutBuff, (sLen = 15));
    pHex = HexShortToString(sVal, pOutBuffHex, sLen);
    printf (" sVal = %d  ShortToString() p = %s, 0x%x pHex=%s len = %d\n", sVal, p, sVal, pHex, sLen);
    p = ShortToString((sVal = -12345), pOutBuff, (sLen = 15));
    pHex = HexShortToString(sVal, pOutBuffHex, sLen);
    printf (" sVal = %d  ShortToString() p = %s, 0x%x pHex=%s len = %d\n", sVal, p, sVal, pHex, sLen);
    p = ShortToString((sVal = 32767), pOutBuff, (sLen = 15));
    pHex = HexShortToString(sVal, pOutBuffHex, sLen);
    printf (" sVal = %d  ShortToString() p = %s, 0x%x pHex=%s len = %d\n", sVal, p, sVal, pHex, sLen);
    p = ShortToString((sVal = -32767), pOutBuff, (sLen = 15));
    pHex = HexShortToString(sVal, pOutBuffHex, sLen);
    printf (" sVal = %d  ShortToString() p = %s, 0x%x pHex=%s len = %d\n", sVal, p, sVal, pHex, sLen);

    return 0;
}

which produces the following output.

 sVal = 0  ShortToString() p = 0, 0x0 pHex=0 len = 15
 sVal = 0  ShortToString() p = 0 len = 2
 sVal = 1  ShortToString() p = 1, 0x1 pHex=1 len = 15
 sVal = -1  ShortToString() p = -1, 0xffffffff pHex=FFFF len = 15
 sVal = 12  ShortToString() p = 12, 0xc pHex=C len = 15
 sVal = -12  ShortToString() p = -12, 0xfffffff4 pHex=FFF4 len = 15
     sVal = 12  ShortToString() p = *, 0xc pHex=C len = 2
     sVal = -12  ShortToString() p = *, 0xfffffff4 pHex=* len = 2
     sVal = 12  ShortToString() p = 12, 0xc pHex=C len = 3
     sVal = -12  ShortToString() p = **, 0xfffffff4 pHex=** len = 3
     sVal = 12  ShortToString() p = 12, 0xc pHex=C len = 4
     sVal = -12  ShortToString() p = -12, 0xfffffff4 pHex=*** len = 4
     sVal = -12  ShortToString() p = -12, 0xfffffff4 pHex=FFF4 len = 5
 sVal = 103  ShortToString() p = 103, 0x67 pHex=67 len = 15
 sVal = -103  ShortToString() p = -103, 0xffffff99 pHex=FF99 len = 15
 sVal = 100  ShortToString() p = 100, 0x64 pHex=64 len = 15
 sVal = -100  ShortToString() p = -100, 0xffffff9c pHex=FF9C len = 15
 sVal = 123  ShortToString() p = 123, 0x7b pHex=7B len = 15
 sVal = -123  ShortToString() p = -123, 0xffffff85 pHex=FF85 len = 15
 sVal = 1234  ShortToString() p = 1234, 0x4d2 pHex=4D2 len = 15
 sVal = -1234  ShortToString() p = -1234, 0xfffffb2e pHex=FB2E len = 15
 sVal = 12345  ShortToString() p = 12345, 0x3039 pHex=3039 len = 15
 sVal = -12345  ShortToString() p = -12345, 0xffffcfc7 pHex=CFC7 len = 15
 sVal = 32767  ShortToString() p = 32767, 0x7fff pHex=7FFF len = 15
 sVal = -32767  ShortToString() p = -32767, 0xffff8001 pHex=8001 len = 15
Richard Chambers
  • 16,643
  • 4
  • 81
  • 106