Search code examples
arduinonumberscalculatorinfrared

Converting the number after another number into a 2 algarisms number? (1 then 1 = 11) - Arduino


So, I'm trying to set up a kind of calculator with Arduino. I've already managed to read the data from an IR Remote Control and display them in a LCD 16x2 Display. If I type "1", for example, "1" will be showed on the display, but how do I manage to make the program understand that if two, or more numbers were pressed before the Enter button it's a number with more than 1 algarism? Like pressing 1, then 2 and then 3 is equal to one hundred and twenty three?

I could make a LOT of if statements to do something like "if 1 was pressed after an existing 1 than variable == 11" and so on, but that's not useful.

Anyway, how can I do this? Or can you point me towards the name of this kind of function/algorithm so I can look forward to it.

Thanks.


Solution

  • Here are two ways to go about this. 1st will simply concatenate a string type and convert it to integer when finished by Carriage Return.

    #define _CR 13
    String readString;
    
    void setup() {
      Serial.begin(9600);
    }
    
    void loop() {
      while (Serial.available()) {
        char c = Serial.read();  //gets one byte from serial buffer
        readString += c; //makes the string readString
        delay(2);  //slow looping to allow buffer to fill with next character
      }
    
      if ((readString.length() >0) || ( c == CR_)) {
        Serial.println(readString);  //so you can see the captured string 
        int n = readString.toInt();  //convert readString into a number
    
        // do whatever you want
        // ...
        //
        //
    
        readString=""; //empty for next input
      } 
    }
    

    The other way is by using an Inter Character Timeout. Note that normally

    while (!Serial.available()) {
      // wait for Serial input
    };
    inkey = Serial.read();
    

    is blocking. The below uses pointers of char array to build up the input, up to 5 digits the length of an int16_t (i.e. 65535). hmm it only deals with positives. But you can tweak it to get negatives, and other commands such as "+", "-", etc...

    The reason I use the ICT method, is because the Arduino's IDE Serial Monitor utility defaults to No LF/CR. which just sends the input at once without any LF/CR.

    int16_t last_ms_char; // milliseconds of last recieved character from Serial port.
    int8_t buffer_pos; // next position to recieve character from Serial port.
    char buffer[6]; // 0-35K+null
    int16_t fn_index;
    int16_t Serial_Input_Number;
    
    void setup() {
    
      Serial.begin(115200);
      last_ms_char = millis(); // stroke the inter character timeout.
      buffer_pos = 0; // start the command string at zero length.
    
    }
    
    void loop() {
    
      char inByte;
      if (Serial.available() > 0) {
        inByte = Serial.read();
        if (isDigit(inByte)) { // macro for ((inByte >= '0') && (inByte <= '9'))
          // else if it is a number, add it to the string
          buffer[buffer_pos++] = inByte;
        } else {
          // input char is a letter command
          buffer_pos = 0;
          parse_menu(inByte);
        }
        buffer[buffer_pos] = 0; // update end of line
        last_ms_char = millis(); // stroke the inter character timeout.
    
      } else if ((millis() - last_ms_char) > 500 && ( buffer_pos > 0 )) {
        // ICT expired and have something
        if (buffer_pos == 1) {
          // look for single byte (non-number) menu commands
          parse_menu(buffer[buffer_pos - 1]);
    
        } else if (buffer_pos > 5) {
          // dump if entered command is greater then uint16_t
          Serial.println(F("Ignored, Number is Too Big!"));
    
        } else {
          // otherwise its a number, scan through files looking for matching index.
          Serial_Input_Number = atoi(buffer);
    
          //
          //
          // Do something with "Serial_Input_Number"
          // one time here. Or set flag and do something out of this big if
          // ...
          //
          //
    
    
        }
    
        //reset buffer to start over
        buffer_pos = 0;
        buffer[buffer_pos] = 0; // delimit
    
        //
        //
        // do other stuff repeatedly between new characters
        // ...
        //
        //
      }
    

    No guarantee on the exact code as it was sniped and trimmed from larger examples, that do work.