// Showing how to easly recieve a string from the Serial monitor.
// WITHOUT BLOCKING. Print it on an LCD. AND.. Blink the LCD's text
// insertion point. WITHOUT BLOCKING.
//
// serialStr manages a serial port for you. When it recieves a
// complete string, it calls your choosen function to deal with it.
// And, it does all this, NON-BLOCKINGLY.
//
// timeObj gives you a simple timer that usese ms as a float to set
// it's duration. It can polled if it has expired. -ding- Just like
// a real timer. Even better you can create as many as you would like.
//
//                  Hide the mess of millis!
//

#include <LiquidCrystal.h>
#include <serialStr.h>
#include <timeObj.h>

LiquidCrystal lcd(7, 8, 9, 10, 11, 12);   // The display
timeObj       curserTimer(250);           // Time the blink.
bool          curserOn;                   // We seeing it or not?
serialStr     portManager;                // Gets strings, NON BLOCKINGLY


void setup() {
  
  Serial.begin(115200);
  lcd.begin(16, 2);
  lcd.clear();
  curserOn = false;
  portManager.setCallback(gotStr);    // Got string? Call this.
  Serial.println("Type a string.");
}


// When a string comes in the serial port, this is called.
void gotStr(char* inStr) {

  int i;

  lcd.clear();                  // Clear out display.
  lcd.setCursor(0,0);           // Set to starting point.
  i = 0;                        // Zero out char index.
  while(i<16 && inStr[i]) {     // Line one.
    lcd.print(inStr[i++]);      // Print this char.
  }                             //
  if (inStr[i]) {               // There's more?
    lcd.setCursor(0,1);         // Line two.
    while(i<32 && inStr[i]) {   // Loop through second batch..
      lcd.print(inStr[i++]);    // Print this char.
    }
  }
}


void updateCursor() {

  if (curserTimer.ding()) {
    curserOn = !curserOn;
    if (curserOn) lcd.cursor();
    else lcd.noCursor();
    curserTimer.stepTime();
  } 
}


void loop() {

  idle();         // Runs the serial port in this instance.
  updateCursor(); // Amuses the user.
}