Display Routines - Arduino

Fixed Width Binary and Hexadecimal and Float

copyright, Peter H. Anderson, Baltimore, MD, Nov, '07


Discussion.

Routines are presented for displaying positive integers in binary and hexadecimal with specified fixed widths. This arose from some frustration in looking at the various ATMega registers using the Serial.print to display in either binary or hexadecimal format where leading zeros are suppressed.

For example;

   x = 3;
   Serial.print(x, BIN);
   Serial.print(x, HEX);
will print;
   11
   F

PRINT_BINARY, PRINT_HEX.

In these routines, the number of places may be specified. For example;


    x = 15;
    print_binary(x, 8);
    print_hex(x, 8);

will print;
    0000_1111
    0F


// PRINT_BINARY - Arduino
//
// Prints a positive integer in binary format with a fixed withdth
//
// copyright, Peter H Anderson, Baltimore, MD, Nov, '07

void setup()                    // run once, when the sketch starts
{
   Serial.begin(9600);
}

void loop()
{
  while(1)
  {
      print_binary(1024+256+63, 12);
      Serial.println();
      delay(1000);

  }
}

void print_binary(int v, int num_places)
{
    int mask=0, n;

    for (n=1; n<=num_places; n++)
    {
        mask = (mask << 1) | 0x0001;
    }
    v = v & mask;  // truncate v to specified number of places

    while(num_places)
    {

        if (v & (0x0001 << num_places-1))
        {
             Serial.print("1");
        }
        else
        {
             Serial.print("0");
        }

        --num_places;
        if(((num_places%4) == 0) && (num_places != 0))
        {
            Serial.print("_");
        }
    }
}


// PRINT_HEX - Arduino  ATMega168
//
// Illustrates how to display a hexadecimal number with a fixed width.
//
// copyright, Peter H Anderson, Baltimore, MD, Nov, '07

void setup()                    // run once, when the sketch starts
{
   Serial.begin(9600);
}

void loop()
{
  while(1)
  {
      print_hex(1024+256+63, 13);
      Serial.println();
      delay(1000);

  }
}

void print_hex(int v, int num_places)
{
    int mask=0, n, num_nibbles, digit;

    for (n=1; n<=num_places; n++)
    {
        mask = (mask << 1) | 0x0001;
    }
    v = v & mask; // truncate v to specified number of places

    num_nibbles = num_places / 4;
    if ((num_places % 4) != 0)
    {
        ++num_nibbles;
    }

    do
    {
        digit = ((v >> (num_nibbles-1) * 4)) & 0x0f;
        Serial.print(digit, HEX);
    } while(--num_nibbles);

}


PRINT_FLOAT.


// PRINT_FLOAT - Arduino
//
// Illustrates how to display floats in the range of -999.999 to 999.999 with a specified
// number of digits after the decimal point.
//
// copyright, Peter H Anderson, Baltimore, MD, Nov, '07

void setup()                    // run once, when the sketch starts
{
   Serial.begin(9600);
}

void loop()
{
  while(1)
  {
      print_float(0.6, 2);   // illustrate various test cases
      Serial.println();
      print_float(1.2, 1);
      Serial.println();
      print_float(10.27, 2);
      Serial.println();
      print_float(10.345, 3);
      Serial.println();
      print_float(107.345, 3);
      Serial.println();
      delay(1000);

      print_float(-0.6, 2);
      Serial.println();
      print_float(-1.2, 1);
      Serial.println();
      print_float(-10.27, 2);
      Serial.println();
      print_float(-10.345, 3);
      Serial.println();
      print_float(-107.345, 3);
      Serial.println();
      delay(1000);
  }
}

void print_float(float f, int num_digits)
{
    int f_int;
    int pows_of_ten[4] = {1, 10, 100, 1000};
    int multiplier, whole, fract, d, n;

    multiplier = pows_of_ten[num_digits];
    if (f < 0.0)
    {
        f = -f;
        Serial.print("-");
    }
    whole = (int) f;
    fract = (int) (multiplier * (f - (float)whole));

    Serial.print(whole);
    Serial.print(".");

    for (n=num_digits-1; n>=0; n--) // print each digit with no leading zero suppression
    {
         d = fract / pows_of_ten[n];
         Serial.print(d);
         fract = fract % pows_of_ten[n];
    }
}