Go Down

Topic: Bin Dec Hex Oct Converter (Read 1 time) previous topic - next topic

kopite

Quote
If I read the code correctly you are assuming one or two digit input. What if someone enters 0004?

You are best off:

    Collect the input into a buffer, delimited by something (eg. newline)
    Do a conversion on that buffer


My link above shows exactly how to do that for decimal numbers, so it shouldn't take weeks to do.


Apologies for my lack of knowledge (as a beginner)-Ive looked at your link but i dont understand exactly what bit (excuse the pun) I should be looking at. I dont exactly understand it all and how i can apply this to my code.

Thanks.

Nick Gammon

I've had a go at doing something along those lines. Perhaps it isn't entirely trivial. I don't want to do your homework for you, but the code below partly solves your problem. I'll leave it up to you to flesh out the other input and output bases:

Code: [Select]

// Example of receiving numbers by Serial
// Author: Nick Gammon
// Date: 16 December 2012

typedef enum { eWantMenu, eWantResponse, eWantFirstDigit, eWantDigit } states;

states state = eWantMenu;

bool negative = false;
long receivedNumber = 0;

int inputBase, outputBase;

void setup ()
  {
  Serial.begin (115200);
  Serial.println (F("Starting ..."));
  } // end of setup
 
void showNumber ()
  {
  char buf [20];
  ltoa (receivedNumber, buf, outputBase);
  Serial.print ("Result = ");
  Serial.println (buf);
  }  // end of showNumber
 
void processDigit (byte c)
  {
  if (c < 0 || c >= inputBase)
    {
    Serial.print (F("Digit "));
    Serial.print ((char) c);
    Serial.println (F(" out of range for selected base."));
    state = eWantMenu;
    return;
    }
   
  receivedNumber *= inputBase;
  receivedNumber += c;
  }  // end of processDigit
 
void processInput ()
  {
 
  byte c = Serial.read ();
 
  if (state == eWantResponse)
    {
    // ignore spaces, newlines
    if (isspace (c))
      return;
     
    switch (c)
      {
       
      // put other ones here ...
     
      case 'j':   // decimal to binary
          inputBase = 10;
          outputBase = 2;
          break;

      case 'k':   // decimal to hex
          inputBase = 10;
          outputBase = 16;
          break;
     
      default: 
        Serial.println (F("Unknown response."));
        state = eWantMenu;
        return;
      }
     
    receivedNumber = 0;
    negative = false;
    state = eWantFirstDigit;
    Serial.print (F("Enter your number in the base "));
    Serial.print (inputBase);
    Serial.println (F(" ... "));
   
    return;       
    }  // end of eWantResponse
   
  // skip spaces, newlines, until we get a digit
  if (state == eWantFirstDigit && !isxdigit (c))
    return;
   
  state = eWantDigit;
 
  switch (c)
    {
     
    case '\n': 
        showNumber ();
        state = eWantMenu;
        break;
     
    case '0' ... '9':
      processDigit (c - '0');
      break;

    case 'A' ... 'F':
      processDigit (c - 'A' + 10);
      break;

    case 'a' ... 'f':
      processDigit (c - 'a' + 10);
      break;
     
    case '-':
      negative = true;
      break;
     
    } // end of switch 
  }  // end of processInput
 
void loop ()
  {
 
  if (state == eWantMenu)
    {
    Serial.println(F("Welcome to my Bin, Dec, Oct, Hex Converter"));
    delay(500);
    Serial.println(F(" "));
    Serial.println(F("Please select a number from the options available..."));
    Serial.println(F("*Please Note* The options below are Case Sensitive!"));
    Serial.println(F(" "));
    Serial.println(F("Main Menu"));
    Serial.println(F("---------"));
    Serial.println(F("a) 2's comp Binary to Hex,"));
    Serial.println(F("b) 2's comp Binary to Octal,"));
    Serial.println(F("c) 2's comp Binary to Decimal,"));
    Serial.println(F("d) Octal to 2's comp Binary,"));
    Serial.println(F("e) Octal to Hex,"));
    Serial.println(F("f) Octal to Decimal,"));
    Serial.println(F("g) Hex to 2's comp Binary,"));
    Serial.println(F("h) Hex to Octal,"));
    Serial.println(F("i) Hex to Decimal,"));
    Serial.println(F("j) Decimal to 2's comp Binary,"));
    Serial.println(F("k) Decimal to Hex,"));
    Serial.println(F("l) Decimal to Octal."));
    state = eWantResponse;   
   
    // throw away any input from before
    while (Serial.available ())
      Serial.read ();
    }
   
  if (Serial.available ())
    processInput ();

  } // end of loop


I've used a state machine to know what we are up to (getting a response, getting a number). You'll need to add other input and output bases, and do something with negative numbers.

kopite

Hi, does anyone know a simple way to read serial input as binary.

To clarify instead of taking an input say number 1 (ascii 49) and reading it as its binary format i want a user to be able to input a binary value say 00101011 in binary format.

Ive tried using byte but when using the serialRead function, quite simply nothing works so ive gone back to the drawing board to see if anyone has a simple solution.

Also how could i take serial read as an octal value, so the user could put in 012 (Dec = 10) and treat it as octal.

Many thanks.

AWOL

Quote
Also how could i take serial read as an octal value, so the user could put in 012

That's an interesting question.
What if you entered 011?
Would you interpret as 3 or 9?
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Nick Gammon

You decided to ask the same question again, huh?

Please do not cross-post. This wastes time and resources as people attempt to answer your question on multiple threads.

Threads merged.

- Moderator

Go Up