Search code examples
c++cembeddeduart

ASCII to int to ASCII (ATMEGA 2560)


I'm trying to make a embedded c project where i will input 7 chars and make some calculations with them - now i got problem getting my conversion to work - I'm working with a ATMEGA 2560, where I output the chars on uart.

Here's the code:

volatile char daata[8] = "123:456\0";
volatile char recdata[8];
volatile char data = 0;
volatile char byte;
volatile int minimum;
volatile int maximum;
volatile char mx;
volatile char mi;

and my function uses:

void putsUSART0(char *ptr)
{
    while(*ptr)
    {
        putchUSART0(*ptr);
        ptr++;
    }
}

and

void putchUSART0(char tx)
{
    while(!(UCSR0A & (1 << UDRE0)));   // wait for empty transmit buffer

    UDR0 = tx;
}

where the code im working on is:

minimum = (100 * (daata[0] - 0x30) + 10 * (daata[1] - 0x30) + daata[2] - 0x30);
maximum = daata[6] - 0x30 + 10 * (daata[5] - 0x30) + 100 * (daata[4]);

mi = minimum + 0x30;
putsUSART0("mimimum is:");
//putchUSART0(minimum );
putsUSART0(mi);
putsUSART0("maximum is:");
putchUSART0(maximum);
_delay_ms(5000);
status = requestsample;

The problem is that my output is

mimimum is:maximum is:ˆ

Can anyone explain the strange behavior.


Solution

  • char buf[15];
    ...
    mi = minimum + 0x30;
    sprintf(buf, "%d", mi);
    putsUSART0("mimimum is:");
    //putchUSART0(minimum );
    putsUSART0(buf);
    

    Do similar for maximum also

    You are sending the value of ASCII character (and trying to convert it to character by adding 0x30 which is not the right way, you need to convert all digits) and possibly printing it without conversion at the other end.


    From kind comment of Lundin

    sprintf() is probably not an option, as this is an embedded project, where that function usually is far too slow and memory-consuming.

    You can also write your own function that can convert a number to string:

    const char *numToStr(int n) {
      /* Non-reentrant, returned buffer will be invalidated on subsequent call */
    #define BUF_SIZE 15
      static char buf[BUF_SIZE] = {0};
      int pos = BUF_SIZE - 1;
      int neg = 0;
      if(n < 0) {
        neg = 1;
        n *= -1;
      }
      do {
        buf[--pos] = (n % 10) + '0';
        n /= 10;
      } while(n);
      if(neg) buf[--pos] = '-';
      return &buf[pos];
    }
    

    And use this to convert number to string.


    From kind comment of Chux

    Fails for numToStr(INT_MIN) Suggest if(n < 0) { neg = 1; } else { n = -n; } do { buf[--pos] = '0' - (n % 10); n /= 10; } while(n);

    A version to handle INT_MIN can be written as:

    const char *numToStr(int n) {
      /* Non-reentrant, returned buffer will be invalidated on subsequent call */
    #define BUF_SIZE 15
      static char buf[BUF_SIZE] = {0};
      int pos = BUF_SIZE - 1;
      int neg = 0;
      if(n < 0) {
        neg = 1;
      } else {
        n = -n;
      }
      do {
        buf[--pos] = '0' - (n % 10);
        n /= 10;
      } while(n);
      if(neg) buf[--pos] = '-';
      return &buf[pos];
    }