Arduino como simple terminal VT100

3

Para usar mi GLCD + Arduino como una pantalla para LCD4Linux , usando LCD4Linux SimpleLCD Driver que envía un subconjunto de códigos VT100 (CR y LF).

He logrado aislar los códigos VT100 del texto regular utilizando el siguiente código:

// 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);
  }

}

Por ahora, solo debería limpiar la pantalla cuando se detecta un código VT100 (desagradable, pero para probar las cosas). Sin embargo, lo que sucede es que los códigos VT100 se imprimen de todos modos, probablemente porque GLCD.ClearScreen() consume demasiado tiempo de CPU (?). Cuando no uso ClearScreen , pero simple println la variable vt100Code (que devuelvo desde handleVT100Code() ) el código se imprime (aunque con algunos falsos positivos).

¿Qué tendría que hacer para que mi programa comprenda estos dos códigos VT100 (retorno de carro y avance de línea)? He hecho algunas búsquedas para una implementación inmediata de un simple terminal VT100, pero parece que no hay ninguna. Si hay alguna forma más fácil de usar el GLCD con LCD4Linux, no dude en decírmelo.

    
pregunta peterrus

2 respuestas

5

Parece que tienes un poco de confusión en un par de niveles diferentes aquí.

En primer lugar, CR y LF no son "códigos VT100" como tales, son simplemente caracteres de control ASCII ordinarios (hex 0D / decimal 13 y hex 0A / decimal 10, respectivamente). Los códigos reales de VT100 son secuencias de múltiples bytes que comienzan con un carácter de escape (ESC) (hex 1B / decimal 27), que es lo que su código realmente está detectando. Entonces, a ese nivel, deberías estar manejando CR y LF en el mismo switch() donde estás detectando el ESC.

Ahora, en lo que respecta a las secuencias de código VT100 reales (para colocar el cursor, cambiar colores, etc.), necesita saber cuánto dura cada secuencia, según los caracteres que haya recibido hasta el momento. Una implementación completa puede ser bastante complicada.

Pero el problema con su código es que una vez que reconoce el carácter ESC, llama a handleVT100Code() . Esta función tiene un bucle while() , pero la condición solo será verdadera si ya se ha recibido ya el siguiente carácter de la secuencia. Dadas las velocidades relativas de la CPU y la línea serie, no lo será. Si no, el bucle y la función salen inmediatamente, y termina procesando esos bytes en su bucle principal. En realidad, tendrá que esperar en handleVT100Code() para los bytes que siguen a la ESC.

    
respondido por el Dave Tweed
1
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);
  }

}

Gracias Dave por darme la información;) Ahora necesitaré implementar el verdadero manejo de los códigos VT100, pero eso solo debería ser una cuestión de análisis de cadenas.

    
respondido por el peterrus

Lea otras preguntas en las etiquetas