3
\$\begingroup\$

In order to use my GLCD + Arduino as a display for LCD4Linux, using the LCD4Linux SimpleLCD Driver which sends out a subset of VT100 codes (CR and LF).

I have managed to isolate the VT100 codes from regular text using the following code:

// include the library code:
#include <glcd.h>

// include the Fonts

#include <fonts/allFonts.h>

void setup() {
  // Initialize the GLCD 
  GLCD.Init();

  // Select the font for the default text area
  GLCD.SelectFont(System5x7);
  GLCD.ClearScreen();
  GLCD.println("Please wait:  "); // output using Print class
  GLCD.println("  System initializing"); // output using Print class

  // could also use gText string output routine
  // GLCD.Puts("Listening...\n"); 
  Serial.begin(9600);
}

void loop()
{
  char c;

  // when characters arrive over the serial port...
  if (Serial.available())
  {
    // read character from serial library buffer
    c = Serial.read();

    switch(c)
    {
    case 27:
      if(handleVT100Code())
      {
        GLCD.ClearScreen();
      }
      break;
    default:
      // display character on glcd
      GLCD.write(c); // use Print class for output 
      break;
    }
  }
}

boolean handleVT100Code()
{
  char c;

  String vt100Code;

  while(Serial.available())
  {
    c = Serial.read();

    vt100Code.concat(c);
    if(c == 'H')
    {
      break;
    }
  }

  if(vt100Code != "")
  {
    return(true);
  }

}

So for now it should only clear the screen when a VT100 code is detected (nasty, but to test things out). What happens, however, is that the VT100 codes get printed out anyway, probably because GLCD.ClearScreen() takes up too much cpu time (?). When I don't use ClearScreen, but simple println the vt100Code variable (which I return from handleVT100Code()) the code gets printed (albeit with some false positives).

What would I have to do to make my program understand these two VT100 Codes (Carriage return and Line feed). I have done quite some searches for an out of the box implementation of a simple VT100 terminal, but there seem to be none. If there is some easier way of using the GLCD with LCD4Linux, you are more than welcome to tell me.

\$\endgroup\$
5
\$\begingroup\$

You seem to have some confusion on a couple of different levels here.

First of all, CR and LF are not "VT100 codes" as such, they're just ordinary ASCII control characters (hex 0D/decimal 13 and hex 0A/decimal 10, respectively). Actual VT100 codes are multi-byte sequences beginning with an escape (ESC) character (hex 1B/decimal 27), which is what your code is actually detecting. So, at that level, you should be handling CR and LF in the same switch() where you're detecting the ESC.

Now, as far as dealing with actual VT100 code sequences (to position the cursor, change colors, etc.) you need to know how long each sequence is, based on the characters you've received so far. A full implementation can be quite involved.

But the problem with your code is that once you recognize the ESC character, you call handleVT100Code(). This function has a while() loop, but the condition will only be true if the next character of the sequence has already been received. Given the relative speeds of the CPU and the serial line, it won't be. If not, the loop and the function exit immediately, and you end up processing those bytes in your main loop. You'll actually have to wait in handleVT100Code() for the bytes that follow the ESC.

\$\endgroup\$
  • \$\begingroup\$ Thanks for your response, with CR and LF I was indeed referring to for example: "<ESC>[{ROW};{COLUMN}H". as for the fact that the program runs faster than the serial line can supply characters, I could add a simple delay(1) for example, but that would be a wild guess. Are there any better ways to do this? \$\endgroup\$ – peterrus Sep 28 '12 at 14:06
  • 1
    \$\begingroup\$ instead of relying on correct timing I could also use while(Serial.available() < 1) {}; , this does not seem to make a difference though. \$\endgroup\$ – peterrus Sep 28 '12 at 14:46
1
\$\begingroup\$
boolean handleVT100Code()
{
  char c;

  String vt100Code;

  while(true)
  {
    //wait until next byte is received
    while(Serial.peek() == -1) {};

    c = Serial.read();

    vt100Code.concat(c);
    if(c == 'H')
    {
      break;
    }
  }

  if(vt100Code != "")
  {
    return(true);
  }

}

Thanks Dave for giving me the insight ;) Now I will need to implement true handling of the VT100 codes, but that should only be a matter of parsing strings.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.