0.2.0 ANSI

This commit is contained in:
rob tillaart 2023-02-27 11:33:43 +01:00
parent 952297a78e
commit 7d84158898
18 changed files with 283 additions and 162 deletions

View File

@ -6,6 +6,17 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
## [0.2.0] - 2023-02-26
- fix #13 gotoXY(column, row)
- add ansi_gotoXY example.
- update all examples with new gotoXY
- improve performance - replace print() => write()
- move all (non experimental) code from .h to .cpp
- update readme.md
- minor edits
----
## [0.1.8] - 2023-01-31
- update readme.md
- update GitHub actions
@ -15,7 +26,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- add example ansi_132_columns.ino
- minor edits
## [0.1.7] - 2022-10-28
- add RP2040 to build-CI
- minor edits

View File

@ -21,6 +21,17 @@ The set of codes is large, however not all terminal types do support all codes.
Sending these ANSI codes to a simple ASCII only terminal like the one in the Arduino
IDE might result in garbage. So use with care.
#### Breaking change 0.2.0
The **gotoXY(x, y)** has changed as the X and Y coordinates were swapped.
The code has been updated to explicitly mention which is row and which is column.
- **gotoXY(uint8_t column, uint8_t row)**
#### Related
https://en.wikipedia.org/wiki/ANSI_escape_code
## Terminals tested
@ -51,19 +62,19 @@ Can be a software serial too.
#### Stream interface
- **int available()**
- **int read()**
- **int peek()**
- **void flush()**
- **int available()** to check if chars are available on the stream.
- **int read()** read a byte from the stream.
- **int peek()** preview the byte in the stream without fetching.
- **void flush()**
Stream interface also includes print(), println(), write().
#### Character modi
- **void normal()** idem.
- **void bold()** idem.
- **void low()** idem.
- **void normal()** normal intensity.
- **void bold()** bold or high intensity.
- **void low()** low intensity.
- **void underline()** idem.
- **void blink()** idem.
- **void reverse()** idem.
@ -74,25 +85,28 @@ Stream interface also includes print(), println(), write().
- **void foreground(uint8_t fgcolor)**
- **void background(uint8_t bgcolor)**
- **void color(uint8_t fgcolor, uint8_t bgcolor)**
Three helpers to map to the nearest colour.
- **uint8_t gray2color(uint8_t gray)**
- **uint8_t grey2color(uint8_t grey)** idem
- **uint8_t rgb2color(uint8_t r, uint8_t g, uint8_t b)**
todo colour table
To do colour table
#### Positioning
- **void clearScreen()**
- **void clearScreen()** clears screen and sets cursor to 0,0.
- **void clearLine(uint8_t clear = toEnd)** toEnd = 0,
toStart = 1,en tireLine = 2,
- **void home()** go to 0,0
- **void gotoXY(uint8_t x, uint8_t y)**
- **void cursorUp(uint8_t x)**
- **void cursorDown(uint8_t x)**
- **void cursorForward(uint8_t x)**
- **void cursorBack(uint8_t x)**
toStart = 1, entireLine = 2,
- **void home()** set cursor to 0, 0
- **void gotoXY(uint8_t column, uint8_t row)** set cursor to position.
Note X == row and Y == column. See #13.
- **void cursorUp(uint8_t x)** idem.
- **void cursorDown(uint8_t x)** idem.
- **void cursorForward(uint8_t x)** idem.
- **void cursorBack(uint8_t x)** idem.
#### Experimental
@ -114,6 +128,9 @@ Since 0.1.5 there is some focus on performance.
Using **ansi.print()** and **ansi.println()** for printing text and numbers is
improved a bit since 0.1.4 by adding the private **write(array, length)**.
Since 0.2.0 the print() statements are replaced by write().
Although it are small improvements these add up.
## Future
@ -130,21 +147,19 @@ improved a bit since 0.1.4 by adding the private **write(array, length)**.
- add examples
- DOS emulator?
- experimental section
- evaluate experimental code
- move code from .h to .cpp
#### Could
- increase functionality
- which codes are generic / useful ?
- investigate performance.
- first step made in 0.1.5 but more possible
- add line buffer in write(c) to improve throughput?
- need for flush() with line buffer?
- rewrite functions, replace print() by **\_stream->write()** calls? (effect on size?)
- move static strings to PROGMEM? as defines?
roughly ~20 bytes progmem for 4 bytes RAM...
- print(char) iso print(string) where possible
#### Wont
- move static strings to PROGMEM? as defines?
roughly ~20 bytes progmem for 4 bytes RAM...

View File

@ -16,6 +16,10 @@ ANSI::ANSI(Stream * stream)
}
//////////////////////////////////////////////////////
//
// STREAM INTERFACE
//
int ANSI::available()
{
return _stream->available();
@ -27,34 +31,118 @@ int ANSI::read()
return _stream->read();
}
int ANSI::peek()
{
return _stream->peek();
}
void ANSI::clearScreen()
void ANSI::flush()
{
// print(F("\033[2J\033[H"));
print("\033[2J");
home();
return;
}
//////////////////////////////////////////////////////
//
// CHAR MODES
//
void ANSI::normal()
{
_stream->write("\033[0m", 3);
}
void ANSI::bold()
{
_stream->write("\033[1m", 3);
}
void ANSI::low()
{
_stream->write("\033[2m", 3);
}
void ANSI::underline()
{
_stream->write("\033[4m", 3);
}
void ANSI::blink()
{
_stream->write("\033[5m", 3);
}
void ANSI::reverse()
{
_stream->write("\033[7m", 3);
}
//////////////////////////////////////////////////////
//
// POSITION COMMANDS
//
void ANSI::clearScreen()
{
_stream->write("\033[2J\033[H", 7);
}
void ANSI::clearLine(uint8_t clear)
{
print("\033[");
_stream->write("\033[", 2);
print(clear);
print("K");
_stream->write('K');
}
void ANSI::home()
{
print("\033[H");
};
_stream->write("\033[H", 3);
}
// changed 0.2.0 see #13
void ANSI::gotoXY(uint8_t column, uint8_t row)
{
_stream->write("\033[", 2);
print(row);
_stream->write(';');
print(column);
_stream->write('H');
}
void ANSI::cursorUp(uint8_t x)
{
_stream->write("\033[", 2);
print(x);
_stream->write('A');
}
void ANSI::cursorDown(uint8_t x)
{
_stream->write("\033[", 2);
print(x);
_stream->write('B');
}
void ANSI::cursorForward(uint8_t x)
{
_stream->write("\033[", 2);
print(x);
_stream->write('C');
}
void ANSI::cursorBack(uint8_t x)
{
_stream->write("\033[", 2);
print(x);
_stream->write('D');
}
//////////////////////////////////////////////////////
//
// COLOR COMMANDS
//
// ANSI has three different color spaces: 4-bit color, 8-bit color, and 24-bit color
// These are rendered with SGR 30-37,90-97/40-47,100-107, SGR 38;5/48;5, and SGR 38;2/48;2, respectively
@ -109,47 +197,6 @@ uint8_t ANSI::rgb2color(uint8_t r, uint8_t g, uint8_t b) {
}
void ANSI::gotoXY(uint8_t x, uint8_t y)
{
print("\033[");
print(x);
print(";");
print(y);
print("H");
}
void ANSI::cursorUp(uint8_t x)
{
print("\033[");
print(x);
print("A");
}
void ANSI::cursorDown(uint8_t x)
{
print("\033[");
print(x);
print("B");
}
void ANSI::cursorForward(uint8_t x)
{
print("\033[");
print(x);
print("C");
}
void ANSI::cursorBack(uint8_t x)
{
print("\033[");
print(x);
print("D");
}
int ANSI::deviceType(uint32_t timeout)
{
@ -174,6 +221,13 @@ int ANSI::deviceType(uint32_t timeout)
}
//////////////////////////////////////////////////
//
// EXPERIMENTAL
//
//////////////////////////////////////////////////
//
// PRIVATE

View File

@ -2,7 +2,7 @@
//
// FILE: ansi.h
// AUTHOR: Rob Tillaart
// VERSION: 0.1.8
// VERSION: 0.2.0
// PURPOSE: Arduino library to send ANSI escape sequences
// DATE: 2020-04-28
// URL: https://github.com/RobTillaart/ANSI
@ -10,7 +10,7 @@
#include "Arduino.h"
#define ANSI_LIB_VERSION (F("0.1.8"))
#define ANSI_LIB_VERSION (F("0.2.0"))
class ANSI : public Stream
@ -22,16 +22,35 @@ public:
int available();
int read();
int peek();
void flush() { return; }; // placeholder to keep CI happy
void flush(); // placeholder to keep CI happy
// CHAR MODES
void normal() { print("\033[0m"); };
void bold() { print("\033[1m"); };
void low() { print("\033[2m"); };
void underline() { print("\033[4m"); };
void blink() { print("\033[5m"); };
void reverse() { print("\033[7m"); };
void normal();
void bold();
void low();
void underline();
void blink();
void reverse();
// POSITIONING
enum {
toEnd = 0,
toStart = 1,
entireLine = 2,
};
void clearScreen();
void clearLine(uint8_t clear = toEnd);
void home();
// gotoXY() changed in 0.2.0 See #13
void gotoXY(uint8_t column, uint8_t row);
void cursorUp(uint8_t x);
void cursorDown(uint8_t x);
void cursorForward(uint8_t x);
void cursorBack(uint8_t x);
// COLOR
@ -72,25 +91,6 @@ public:
uint8_t rgb2color(uint8_t r, uint8_t g, uint8_t b);
// POSITIONING
enum {
toEnd = 0,
toStart = 1,
entireLine = 2,
};
void clearScreen();
void clearLine(uint8_t clear = toEnd);
void home();
void gotoXY(uint8_t x, uint8_t y);
void cursorUp(uint8_t x);
void cursorDown(uint8_t x);
void cursorForward(uint8_t x);
void cursorBack(uint8_t x);
// META
// deviceType is discussed
// - https://github.com/RobTillaart/ANSI/issues/9

View File

@ -1,12 +1,8 @@
//
// FILE: ansiDemo01.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// PURPOSE: demo
// DATE: 2020-04-28
// URL: https://github.com/RobTillaart/ANSI
// (c) : MIT
//
#include "ansi.h"
@ -42,7 +38,7 @@ void setup()
ansi.clearScreen();
for (int i = 1; i < 25; i++)
{
ansi.gotoXY(i, 2 * i);
ansi.gotoXY(2 * i, i);
ansi.println("Hello world");
delay(100);
}
@ -98,4 +94,4 @@ void loop()
}
// -- END OF FILE --
// -- END OF FILE --

View File

@ -1,12 +1,8 @@
//
// FILE: ansiDemo02.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// PURPOSE: demo
// DATE: 2020-04-29
// URL: https://github.com/RobTillaart/ANSI
// (c) : MIT
//
#include "ansi.h"
@ -23,7 +19,7 @@ void setup()
// SPLASH SCREEN
ansi.clearScreen();
ansi.gotoXY(8, 10);
ansi.gotoXY(10, 8);
ansi.bold();
ansi.print("DEMO ANSI TERMINAL");
ansi.normal();
@ -35,27 +31,27 @@ void setup()
void loop()
{
// DISPLAY TEMPERATURE (dummy)
ansi.gotoXY(6, 10);
ansi.gotoXY(10, 6);
ansi.print("TEMP: ");
ansi.gotoXY(6, 16);
ansi.gotoXY(16, 6);
t = random(100);
if (t > 70) ansi.foreground(ansi.red);
ansi.print(t);
ansi.foreground(ansi.white);
// DISPLAY HUMIDITY (dummy)
ansi.gotoXY(7, 10);
ansi.gotoXY(10, 7);
ansi.print(" HUM: ");
ansi.gotoXY(7, 16);
ansi.gotoXY(16, 7);
t = random(100);
if (t > 50) ansi.foreground(ansi.yellow);
ansi.print(t);
ansi.foreground(ansi.white);
// DISPLAY UV (dummy)
ansi.gotoXY(8, 10);
ansi.gotoXY(10, 8);
ansi.print(" UV: ");
ansi.gotoXY(8, 16);
ansi.gotoXY(16, 8);
d = random(10000) * 0.01;
if (d > 30) ansi.foreground(ansi.green);
if (d > 50) ansi.foreground(ansi.yellow);
@ -66,12 +62,12 @@ void loop()
// DISPLAY bargraph (dummy)
ansi.gotoXY(10, 10);
ansi.print(" BAR:");
ansi.gotoXY(10, 16);
ansi.gotoXY(16, 10);
int x = random(10);
for (int i = 0; i < 10; i++) ansi.print(i <= x ? ">" : " ");
// DISPLAY password (dummy)
ansi.gotoXY(12, 10);
ansi.gotoXY(10, 12);
ansi.print("PASS:");
char buffer[20];
for (int i = 0; i < 16; i++)
@ -82,18 +78,18 @@ void loop()
if (52 <= x) buffer[i] = '0' + random(10);
}
buffer[16] = 0;
ansi.gotoXY(12, 16);
ansi.gotoXY(16, 12);
ansi.print(buffer);
// DISPLAY TIME (dummy)
ansi.gotoXY(2, 10);
ansi.gotoXY(10, 2);
ansi.print("TIME: ");
ansi.gotoXY(2, 16);
ansi.gotoXY(16, 2);
ansi.print(millis()/1000);
delay(1000);
}
// -- END OF FILE --
// -- END OF FILE --

View File

@ -3,7 +3,6 @@
// AUTHOR: Rob Tillaart
// PURPOSE: demo clock
// URL: https://github.com/RobTillaart/ANSI
// (c) : MIT
//
// use Tera Term to view 132 columns.
@ -30,7 +29,6 @@ nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui.";
ANSI ansi(&Serial);
void setup()
{
Serial.begin(115200);

View File

@ -1,12 +1,8 @@
//
// FILE: ansi_IO.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// PURPOSE: demo
// DATE: 2021-10-18
// URL: https://github.com/RobTillaart/ANSI
// (c) : MIT
//
#include "ansi.h"
@ -26,7 +22,7 @@ void setup()
ansi.print("ANSI_LIB_VERSION: ");
ansi.print(ANSI_LIB_VERSION);
ansi.gotoXY(4, 2);
ansi.gotoXY(2, 4);
ansi.print("Username: ");
char c = '\0';
while (c != '\r')
@ -42,7 +38,7 @@ void setup()
}
}
ansi.gotoXY(5, 2);
ansi.gotoXY(2, 5);
ansi.print("Password: ");
c = '\0';
while (c != '\r')
@ -58,7 +54,7 @@ void setup()
}
}
ansi.gotoXY(10, 2);
ansi.gotoXY(2, 10);
ansi.print(user);
ansi.print("\t\t");
ansi.print(password);
@ -71,4 +67,4 @@ void loop()
{
}
// -- END OF FILE --
// -- END OF FILE --

View File

@ -1,11 +1,8 @@
//
// FILE: ansi_char_test.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// PURPOSE: brute force char test
// DATE: 2021-10-18
// URL: https://github.com/RobTillaart/ANSI
// (c) : MIT
#include "ansi.h"
@ -36,4 +33,4 @@ void loop()
}
// -- END OF FILE --
// -- END OF FILE --

View File

@ -1,12 +1,8 @@
//
// FILE: ansi_clearline.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// PURPOSE: demo
// DATE: 2020-07-08
// URL: https://github.com/RobTillaart/ANSI
// (c) : MIT
//
#include "ansi.h"
@ -28,7 +24,7 @@ void setup()
for (int i = 0; i < 8; i++)
{
ansi.gotoXY(i, 4 + 2 * i);
ansi.gotoXY(4 + 2 * i, i);
ansi.clearLine(ansi.toEnd);
delay(100);
}
@ -36,7 +32,7 @@ void setup()
for (int i = 12; i < 20; i++)
{
ansi.gotoXY(i, 4 + 2 * i);
ansi.gotoXY(4 + 2 * i, i);
ansi.clearLine(ansi.toStart);
delay(100);
}
@ -44,7 +40,7 @@ void setup()
for (int i = 9; i < 11; i++)
{
ansi.gotoXY(i, 4 + 2 * i);
ansi.gotoXY(4 + 2 * i, i);
ansi.clearLine(ansi.entireLine);
delay(100);
}
@ -57,5 +53,5 @@ void loop()
}
// -- END OF FILE --
// -- END OF FILE --

View File

@ -76,9 +76,9 @@ void display_time_1()
if (now - lastTime >= 1000)
{
lastTime = now;
ansi.gotoXY(2, 10);
ansi.gotoXY(10, 2);
ansi.print("TIME: ");
ansi.gotoXY(2, 16);
ansi.gotoXY(16, 2);
if (hh < 10) ansi.print(0);
ansi.print(hh);
ansi.print(':');
@ -99,9 +99,9 @@ void display_time_2()
if (now - lastTime >= 1000 && (ss % 5 == 0))
{
lastTime = now;
ansi.gotoXY(4, 10);
ansi.gotoXY(10, 4);
ansi.print("TIME: ");
ansi.gotoXY(4, 16);
ansi.gotoXY(16, 4);
if (hh < 10) ansi.print(0);
ansi.print(hh);
ansi.print(':');
@ -122,9 +122,9 @@ void display_time_3()
if (now - lastTime >= 1000)
{
lastTime = now;
ansi.gotoXY(6, 10);
ansi.gotoXY(10, 6);
ansi.print("TIME: ");
ansi.gotoXY(6, 16);
ansi.gotoXY(16, 6);
if (hh < 10) ansi.print(0);
ansi.print(hh);
if (ss & 0x01) ansi.print(':');
@ -135,5 +135,4 @@ void display_time_3()
}
// -- END OF FILE --

View File

@ -33,4 +33,4 @@ void loop()
}
// -- END OF FILE --
// -- END OF FILE --

View File

@ -0,0 +1,50 @@
//
// FILE: ansi_gotoXY.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo
// URL: https://github.com/RobTillaart/ANSI
#include "ansi.h"
ANSI ansi(&Serial);
int t;
double d;
void setup()
{
Serial.begin(115200);
// SPLASH SCREEN
ansi.clearScreen();
ansi.gotoXY(1, 10);
ansi.print("x = 1, y = 10");
delay(2000);
ansi.gotoXY(10, 1);
ansi.print("x = 10, y = 1");
delay(2000);
ansi.gotoXY(5, 20);
ansi.print("x = 5, y = 20");
delay(2000);
ansi.cursorForward(5);
ansi.cursorUp(5);
ansi.print("*");
ansi.cursorForward(5);
ansi.print("*");
ansi.cursorDown(5);
ansi.cursorBack(1);
ansi.print("*");
ansi.cursorBack(7);
ansi.print("*");
}
void loop()
{
}
// -- END OF FILE --

View File

@ -1,12 +1,8 @@
//
// FILE: ansi_performance.ino
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// PURPOSE: start of performance print statement.
// DATE: 2021-12-13
// URL: https://github.com/RobTillaart/ANSI
// (c) : MIT
//
#include "ansi.h"
@ -55,10 +51,13 @@ void setup()
Serial.println(stop - start);
delay(100);
Serial.println("\ndone...");
}
void loop()
{
}
// -- END OF FILE --
// -- END OF FILE --

View File

@ -0,0 +1,14 @@
IDE: 1.8.19
Board: UNO
ansi_performance.ino
0.2.0
PERFORMANCE TEST ANSI TERMINAL PRINT
ANSITERM: 352
PERFORMANCE TEST ANSI TERMINAL PRINT
SERIAL: 300
(cleaned output of clearScreen(); test)
ANSITERM: 52
SERIAL: 56

View File

@ -15,7 +15,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/ANSI.git"
},
"version": "0.1.8",
"version": "0.2.0",
"license": "MIT",
"frameworks": "arduino",
"platforms": "*",

View File

@ -1,5 +1,5 @@
name=ANSI
version=0.1.8
version=0.2.0
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library to send ANSI escape sequences.

View File

@ -19,6 +19,7 @@
// assertFalse(actual)
// assertNull(actual)
#include <ArduinoUnitTests.h>
#include "Arduino.h"
@ -58,4 +59,4 @@ unittest(test_gray2color)
unittest_main()
// --------
// -- END OF FILE --