7
\$\begingroup\$

I think it is possible due to how I can run vi straight from my serial port looking via TeraTerm. There, I can edit some text, go to the next line, then come back and edit the first line! How do they do this?

What character over UART could I send through to go "up a line"?

EDIT: Apparently line feed works. "\f" to clear the screen. However, this only works for Hyperterminal on my machine and not Teraterm. Anyone know why?

\$\endgroup\$

3 Answers 3

12
\$\begingroup\$

Use VT100 escape codes to control the cursor.

Eg.

puts("\033[2J");   // clear screen
puts("\033[0;0H"); // set cursor to 0,0
puts("\033[10B");  // move cursor down 10 lines
puts("\033[5A");  // move cursor up 5 lines
\$\endgroup\$
5
  • \$\begingroup\$ neat I'll have to try this out sometime, but those \ should probably be \\ through right? or does puts actually recognize those entire strings as individual escape codes? I'm used to think of escape codes as a backslash followed by one character... \$\endgroup\$
    – vicatcu
    Commented Jan 11, 2011 at 14:59
  • 1
    \$\begingroup\$ actually, never mind, I see you are using the octal flavor of escape codes and the emitting the escape <ESC> character (0x1B = 033 = 27) as a prefix \$\endgroup\$
    – vicatcu
    Commented Jan 11, 2011 at 15:06
  • \$\begingroup\$ So.. what redraws the screen, in this case? Does the shell just do intelligent echoing? \$\endgroup\$
    – tyblu
    Commented Jan 11, 2011 at 23:29
  • \$\begingroup\$ A real VT100 display would have a framebuffer being continuously redrawn. On a PC, terminal emulators emulate terminals and do the same thing \$\endgroup\$ Commented Jan 11, 2011 at 23:43
  • \$\begingroup\$ I'm pretty sure the upper-left corner of the screen is 1;1 rather than 0;0, but omitted parameters or those specified as zero will be regarded as 1 before the A, B, C, D, or H commands. \$\endgroup\$
    – supercat
    Commented Mar 9, 2011 at 20:06
3
\$\begingroup\$

What you see on a console window is the result of an automatic echo (which can often be turned off or on), where the console program draws the characters you send on the screen, or the result of receiving characters. This means there are two ways of changing it:

  1. Have a local program, on the PC, redraw the screen.
  2. Have the connected device redraw the screen.

There are many ways to do this, but this is how I'd approach a simplistic hobby implementation:

  • Set a default line width, like 80, and number of rows, like 24. Turn off automatic echo.
    alt text
  • An 80x24 screen means 1920 characters per 'frame', which means, if the connected device is doing the work, a maximum refresh rate of around 1920/BAUDRATE/11 or about 5Hz at 115200 baud (using 1 start bit, 1 stop, 1 parity, 8 data).
  • Map the arrow keys to specific characters or strings. This may already be done behind the scenes. (For OSX Terminal, left:\033[5D; right:\033[5C; up & down undefined by default.)
  • Program the connected device to recognize these characters and/or strings, and move the cursor reference accordingly.
  • Output over the serial line not by character or character array, but by frame. Specifically, keep a two 1921 (1920+terminator) character-long arrays: one to write to while the other is being transmitted (assuming the use of hardware UART and interrupts).
  • Writing to the frame buffer can be accomplished by using a function like this:
    uint8_t framewrite(const char *s, uint8_t row, uint8_t col)
    ... Where *s is your [terminated] char array, and row and col are where you want the first character to appear. (Return uint8_t is for error catching.)
  • You'll probably want functions like uint8_t frame_clear(void), uint8_t frame_shiftrowsdown(void), etc.
  • To indicate cursor position you can alternate the current character and a black box or the character of your choice (pblinkchar), using framewrite(pblinkchar,cursor_row,cursor_col).
  • The same method can be used to echo characters back to the cursor position.

I'm sure there are much simpler (I think software guys call it "elegant") ways to do this by programming a PC window, and you can probably figure out how by digging through this tutorial, but the above is similar to what I've done in the past and works for simple user interfaces with micros with plenty of spare memory.

\$\endgroup\$
1
\$\begingroup\$

This is an indirect answer to your question. If you are in VI, then all you need to do to move the cursor up is to send 'k'.

Looking at this VT100 command page, it looks like the up arrow key is represented by sending the following sequence: ESC [ A or 0x1B, 0x5B, 0x41. I don't know if this will work, but I am interested to know if it does.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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