temp sync commit

master
parent 9a2285b53b
commit efd695e54a

@ -9,7 +9,7 @@ Use one include file to replace the Serial.print from Arduino library.
[Using tabular data](#using-tabular-data)
[TerSer Limitations](#terser-limitations)
[Code size and timing comparison](#code-size-and-timing-comparison)
[How to switch from Arduino Serial](#howto_switch)
### What is the problem with Arduino Serial.print ?
Serial.print is is most of the time used as a debugging tool, and with limited resources it is even more important to have the most lighweight solution for this task.
@ -21,6 +21,29 @@ One just uses a bad but widely available tool, and is not willing to find or inv
We propose to use a compact C portable library. Compatibility with an Oled display is a further plus. The SerTerm.h and OledTerm.h are demonstrated on the popular Arduino environment, but it is just plain C.
It is admittedly very convenient to just use Serial.print(var); since it doesn't require you to specify the type of variable. Though when trying for example to output data in tabular style the processor needs to know the data type used so that it can reserve the adequate space for it in its output. It might seem like a big inconvenience to specify the data type with any statement that outputs data over serial but then again for debugging purposes it makes perfectly sense in terms of speed AND size of the resulting code. By the same reasons we also do not use a buffer as it is needed only in specific situations.
The TerSer.h offer the choice of 4 print format for numbers. Signed variables have a + or sign in front.
| Normal (moz=0) | Spaces (moz=1) | Zeros (moz=2) | Compact (moz=3) | Serial.print |
| -------------- | -------------- | -------------- | -------------- | -------------- |
| ![moz0](docs/images/tab_moz0.png?raw=true "Example moz=0") | ![moz1](docs/images/tab_moz1.png?raw=true "Example moz=1") | ![moz2](docs/images/tab_moz2.png?raw=true "Example moz=2") | ![moz3](docs/images/tab_moz3.png?raw=true "Example moz=3") | ![Aserial](docs/images/tab_arduino_serial.png?raw=true "Example Arduino Serial.print") |
<a name="howto_switch"/>
### How to switch from Arduino Serial
If you are looking for a drop-in replacement for Arduino Serial with a smaller memory footprint follow the procedure outlined below to quickly switch your project to Didel TerSer:
* Add **#include <TerSer.h>** at the top of your sketch or select the library from your Arduino IDE (*Sketch* | *Include Library*)
* Use the either the library function names we provide or define your own function names, for example:
`#define Serialprint(x) Text(x)`
* Search for all occurences or `Serial.print` and replace with `Serialprint`
Voila, you have switched to TerSer and enjoy smaller footprint at less mcu cycles
#### Function aliasing
If you do not like our function/method names, feel free to define names that suit your tastes with i.e.:
`#define Serialprint(x) Text(x)`
`#define Serialprint(x,BIN) Bin8(x)`
`#define Serialprint(x,BIN) Bin16(x)`
`#define Serialprint(x) Dec16(x)`
etc.
### TerSer Installation
<a name="example_comparison"/>
### Example comparison between Didel TerSer and Arduino Serial

@ -1,165 +0,0 @@
// TerSer.h Avec zéros non significatifs
// remplace serial.Print TerGet()
// #include "TerSer.h" SetupTerSer();
//Dec8-->Dec8u/s Dec16-->Dec16u/s 190210 jmk 16h
void SetupTerSer() {
UBRR0=F_CPU/(9600*16L)-1; // set speed
UCSR0B=0x18; // -- -- -- rxe txe -- -- --
UCSR0C=0x06; // set mode: 8 data bits, no parity, 1 stop bit
}
// Utilisation avec Pythie
//Rx S1 est toujours en sortie sur Pythie
//Tx S2 aussi, sous controle du 328 si TerOn (S2 ignoré);
//#define TerOn UBRR0=F_CPU/(9600*16L)-1; UCSR0C=0x06; UCSR0B=0x08
//#define TerOff DelMs(3); UCSR0C=0x06; UCSR0B=0
// définir S1 S2 selon applic
byte TerGet() { // read bloquant
while (!(UCSR0A&0x80)); // wait
return UDR0;
}
void TerCar( byte dd) { // write bloquant Ok initial
while(!(UCSR0A&0x20));// wait
UDR0=dd; // OK, send it now!
}
void Echo () {
TerCar ( TerGet() );
}
void TerCR() {
TerCar(13);TerCar(10);
}
void TerText(const char str[]) {
for (byte i=0; i< strlen(str); i++) {
TerCar(str[i]);
}
}
void TerBin8 (byte bb) {
for (byte i=0;i<8;i++) {
if (bb&0x80) TerCar('1');
else TerCar('0');
bb <<= 1;
}
TerCar(' ');
}
char TerConvNibble (byte nn) { // converti 4 bit hexa en Ascii
byte cc;
if (nn<10) {cc = nn + '0';}
else {cc = nn-10 + 'A';}
return cc;
}
void TerHex8 (byte hh) {
byte cc;
cc = TerConvNibble (hh >> 4) ; // ne modifie pas hh
TerCar(cc);
cc = TerConvNibble (hh & 0x0F) ;
TerCar(cc);
TerCar(' '); // space
}
void TerHex16 (uint16_t hh) {
byte cc;
cc = TerConvNibble (hh >> 12) ; TerCar(cc);
cc = TerConvNibble ((hh >> 8)&0x0F) ; TerCar(cc);
cc = TerConvNibble ((hh >> 4)&0x0F) ; TerCar(cc);
cc = TerConvNibble ((hh )&0x0F) ; TerCar(cc);
TerCar(' ');
}
void TerHex12 (uint16_t hh) {
byte cc=0;
cc = TerConvNibble ((hh >> 8)&0x0F) ; TerCar(cc);
cc = TerConvNibble ((hh >> 4)&0x0F) ; TerCar(cc);
cc = TerConvNibble (hh & 0x0F) ; TerCar(cc);
TerCar(' ');
}
void TerHex20 (uint32_t hh) {
byte cc;
cc = TerConvNibble ((hh >> 16)&0x0F) ; TerCar(cc);
cc = TerConvNibble ((hh >> 12)&0x0F) ; TerCar(cc);
cc = TerConvNibble ((hh >> 8 )&0x0F) ; TerCar(cc);
cc = TerConvNibble ((hh >> 4 )&0x0F) ; TerCar(cc);
cc = TerConvNibble (hh & 0x0F) ; TerCar(cc);
TerCar(' ');
}
void TerHex32 (uint32_t hh) {
byte cc;
cc = TerConvNibble ((hh >> 28)&0x0F) ; TerCar(cc);
cc = TerConvNibble ((hh >> 24)&0x0F) ; TerCar(cc);
cc = TerConvNibble ((hh >> 20)&0x0F) ; TerCar(cc);
cc = TerConvNibble ((hh >> 16)&0x0F) ; TerCar(cc);
cc = TerConvNibble ((hh >> 12)&0x0F) ; TerCar(cc);
cc = TerConvNibble ((hh >> 8)&0x0F) ; TerCar(cc);
cc = TerConvNibble ((hh >> 4)&0x0F) ; TerCar(cc);
cc = TerConvNibble ((hh )&0x0F) ; TerCar(cc);
TerCar(' ');
}
uint16_t TerBinDec8 (uint8_t bb) {
uint16_t dd=0;
for (byte i=0; i<8; i++) {
if ((dd & 0x0F)>0x04) {dd += 0x03;}
if ((dd & 0xF0)>0x40) {dd += 0x30;}
dd=dd<<1;
if ((bb & 0x80)) {dd += 1;} //inject bit
bb=bb<<1; // prepare next bit
}
return dd;
}
#define TerDec8(v) \
do { const int16_t vv = (v); \
if(vv<0) { TerDec8S(vv); } \
else { TerDec8U(vv); } \
} while(0)
void TerDec8U (uint8_t hh) {
TerHex12(TerBinDec8(hh));
}
void TerDec8S (int8_t hh) {
if (hh<0) { // négatif
TerCar('-'); hh = -hh;
} else {
TerCar('+');
}
TerHex12(TerBinDec8(hh));
}
uint32_t TerBinDec16 (uint16_t bb) {
uint32_t dd=0;
for (byte i=0; i<16 ; i++) {
if ((dd & 0x000F)>0x0004) {dd += 0x0003;}
if ((dd & 0x00F0)>0x0040) {dd += 0x0030;}
if ((dd & 0x0F00)>0x0400) {dd += 0x0300;}
if ((dd & 0xF000)>0x4000) {dd += 0x3000;}
dd=dd<<1;
if ((bb & 0x8000)) {dd += 1; } //inject bit
bb<<=1; // prepare next bit
}
return dd;
}
void TerDec9999 (uint16_t hh) { // limité à 0x2703
if (hh>9999) { TerText("over "); }
else TerHex16(TerBinDec16(hh));
}
#define TerDec16(v) \
do { const int32_t vv = (v); \
if(vv<0) { TerDec16S(vv); } \
else { TerDec16U(vv); } \
} while(0)
void TerDec16U (uint32_t hh) { //
TerHex20(TerBinDec16(hh));
}
void TerDec16S (int16_t hh) { // signé
if (hh<0) { // negatif
TerCar('-'); hh = -hh;
} else {
TerCar('+');
}
TerHex20(TerBinDec16(hh));
}

Binary file not shown.

@ -1,13 +0,0 @@
//TestTerSerEmpty.ino Terminal série et aff nombres
#include "TerSer.h"
void setup() {
SetupTerSer();
}
void loop() {
TerText("Empty"); TerCR();
}

@ -1,97 +1,33 @@
//TestTerSer.ino Terminal série et aff nombres
#include "TerSer.h"
#define Serialprint(v,BIN) TerBin8(v)
int16_t v16s; uint16_t v16; uint8_t v8;
void setup() {
SetupTerSer();
}
uint8_t v8;
int8_t v8s;
uint16_t var;
int16_t vars;
void loop() {
TerText("Test TerSer.h"); TerCR();
Serialprint(0x35,BIN);
TerCR();TerCR();
v8=127; v8s=127; TerHex8(v8); TerDec8(v8); TerDec8(v8s); TerCR();
v8=129; v8s=129; TerHex8(v8); TerDec8(v8); TerDec8(v8s); TerCR();
v8=255; v8s=255; TerHex8(v8); TerDec8(v8); TerDec8(v8s); TerCR();
var=1025;vars=1025;
TerHex16(var); //6ms
TerDec9999(var);
TerDec16(var);
TerDec16(vars);
TerCR();
var=2049;vars=2049;
TerHex16(var); //6ms
TerDec9999(var);
TerDec16(var);
TerDec16(vars);
TerCR();
var=4097;vars=4097;
TerHex16(var); //6ms
TerDec9999(var);
TerDec16(var);
TerDec16(vars);
TerCR();
var=8193;vars=8193;
TerHex16(var); //6ms
TerDec9999(var);
TerDec16(var);
TerDec16(vars);
TerCR();
var=16385;vars=16385;
TerHex16(var); //6ms
TerDec9999(var);
TerDec16(var);
TerDec16(vars);
TerCR();
var=32767;vars=32767;
TerHex16(var); //6ms
TerDec9999(var);
TerDec16(var);
TerDec16(vars);
TerCR();
var=32769;vars=32769;
TerHex16(var); //6ms
TerDec9999(var);
TerDec16(var);
TerDec16(vars);
TerCR();
var=65535;vars=65535;
TerHex16(var); //6ms
TerDec9999(var);
TerDec16(var);
TerDec16(vars);
TerCR();
while (1) {
v8=TerGet();
TerCar(v8);
Echo();
}
void loop(){ // empty 456 bytes 16 var
Textln("Test TerSer");
v8= 19; Bin8(v8); CR();
v16= 1000; Hex16(v16); CR();
v16s= 0; Dec16(v16s);CR();
v16s= 5; Dec16(v16s);CR();
v16s= 23124; Dec16(v16s);CR();
v16s= -200; Dec16(v16s);CR();
v16= 200; Dec16(v16);CR();
for(;;);
}
/*
Test TerSer.inc
7F 127 +127
81 129 -127
FF 255 -001
0401 1025 01025 +01025
0801 2049 02049 +02049
1001 4097 04097 +04097
2001 8193 08193 +08193
4001 over 16385 +16385
7FFF over 32767 +32767
8001 over 32769 +32767
FFFF over 65535 +00001
Size is 1014 bytes on my PC -0s Compare witz TestSerial
What you should see, size is 1032 bites on my PC -0s
Test TerSer
00010011
03E8
0
+5
+23124
-200
200
*/

@ -0,0 +1,41 @@
#######################################
# Syntax Coloring Map
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
TerSer KEYWORD1
moz KEYWORD1
uni KEYWORD1
diz KEYWORD1
cen KEYWORD1
mil KEYWORD1
dim KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
SetupTerSer KEYWORD2
Bin8 KEYWORD2
Bin16 KEYWORD2
BinDec8 KEYWORD2
BinDec16 KEYWORD2
Dec8u KEYWORD2
Dec8s KEYWORD2
Dec16u KEYWORD2
Dec16s KEYWORD2
Hex8 KEYWORD2
Hex16 KEYWORD2
Hex32 KEYWORD2
Get KEYWORD2
Car KEYWORD2
CR KEYWORD2
Text KEYWORD2
Textln KEYWORD2
TtBin8 KEYWORD2
ConvNibble KEYWORD2
Af3Dig KEYWORD2
Af5Dig KEYWORD2

@ -0,0 +1,9 @@
name=Didel TerminalSerial Library
version=1.0.0
author=Didel <info@didel.com>
maintainer=Boxtec <info@boxtec.ch>
sentence=Tiny Footprint serial drop-in replacement Library.
paragraph=A replacement Library for the Arduino Serial Library with a tiny footprint and less execution time. Features special methods for tabular data output over serial.
category=Communication
url=https://git.boxtec.ch/didel/TerSer
architectures=*

@ -0,0 +1,275 @@
// TerSer.h 4 modes 190318
// 280 lines 7775 car
//add in main program #include "TerSer.h" SetupTerSer();
void SetupTerSer() {
UBRR0= 103; // 9600
UCSR0B=0x18; // -- -- -- rxe txe -- -- --
UCSR0C=0x06; // set mode: 8 data bits, no parity, 1 stop bit
}
byte moz=0; // Default value
#define Normal moz=0
#define Spaces moz=1
#define Zeros moz=2
#define Compact moz=3
byte Get() { // read bloquant
while (!(UCSR0A&0x80)); // wait
return UDR0;
}
void Car( byte dd) { // write bloquant
while(!(UCSR0A&0x20));// wait
UDR0=dd; // OK, send it now!
}
void CR() {
Car(13);Car(10);
}
void Text(const char str[]) {
for (byte i=0; i< strlen(str); i++) { Car(str[i]); }
}
void Textln(const char str[]) {
for (byte i=0; i< strlen(str); i++) { Car(str[i]); }
Car(13);Car(10);
}
void TtBin8 (byte bb) { // auxiliary function
for (byte i=0;i<8;i++) {
if (bb&0x80) Car('1');
else Car('0');
bb <<= 1;
}
}
void Bin8 (byte bb) {
TtBin8 (bb); Car(' ');
}
void Bin16 (uint16_t bb) {
TtBin8 (bb>>8); Car('.');
TtBin8 (bb&0xFF);
Car(' ');
}
char ConvNibble (byte nn) { // converti 4 bit hexa en Ascii
byte cc;
if (nn<10) {cc = nn + '0';}
else {cc = nn-10 + 'A';}
return cc;
}
void Hex8 (byte hh) {
byte cc;
cc = ConvNibble (hh >> 4); Car(cc);
cc = ConvNibble (hh & 0x0F) ; Car(cc);
Car(' '); // space
}
void Hex16 (uint16_t hh) {
volatile uint8_t cc;
cc = ConvNibble (hh >> 12) ; Car(cc);
cc = ConvNibble ((hh >> 8)&0x0F) ; Car(cc);
cc=hh&0xFF; Hex8 (cc);
Car(' ');
}
void Hex32 (uint32_t hh) {
volatile uint8_t cc;
cc = ConvNibble (hh >> 28) ; Car(cc);
cc = ConvNibble ((hh >> 24)&0x0F) ; Car(cc);
cc = ConvNibble ((hh >> 20)&0x0F) ; Car(cc);
cc = ConvNibble ((hh >> 16)&0x0F) ; Car(cc);
cc=hh&0xFFFF; Hex16 (cc);
Car(' ');
}
// -- new functions with 4 modes
volatile uint8_t uni,diz,cen,mil,dim;
volatile uint8_t tyn; // type number
volatile uint8_t sig;
void Af5() {Car(dim+'0'); Car(mil+'0'); Car(cen+'0'); Car(diz+'0'); Car(uni+'0'); Car(' ');}
void BinDec8 (uint8_t bb) {
uni=0;diz=0;cen=0;
tyn=0; if (bb==0) return;
uni=bb%10; bb=bb/10; if (bb==0){tyn=1;return;}
diz=bb%10; bb=bb/10; if (bb==0){tyn=2;return;}
cen=bb; tyn=3;
}
void Af3Dig() {
switch (moz) {
case 0: // Normal signe devant le nombre
switch (tyn) {
case 0:
Car(' '); Car(' ');Car(' ');Car('0'); Car(' '); break;
case 1:
Car(' ');Car(' '); Car(sig); Car(uni+'0'); Car(' '); break;
case 2:
Car(' '); Car(sig); Car(diz+'0'); Car(uni+'0'); Car(' '); break;
case 3:
Car(sig); Car(cen+'0'); Car(diz+'0'); Car(uni+'0'); Car(' '); break;
} // end switch tyn
break; // case moz 0
case 1: // Spaces
switch (tyn) {
case 0:
Car(' '); Car(' ');Car(' ');Car('0'); Car(' '); break;
case 1:
Car(sig);Car(' '); Car(' '); Car(uni+'0'); Car(' '); break;
case 2:
Car(sig); Car(' '); Car(diz+'0'); Car(uni+'0'); Car(' '); break;
case 3:
Car(sig); Car(cen+'0'); Car(diz+'0'); Car(uni+'0'); Car(' '); break;
} // end switch tyn
break; // case moz 1
case 2: // Zeros
switch (tyn) {
case 0:
Car(' '); Car('0');Car('0');Car('0'); Car(' '); break;
case 1:
Car(sig);Car('0'); Car('0'); Car(uni+'0'); Car(' '); break;
case 2:
Car(sig); Car('0'); Car(diz+'0'); Car(uni+'0'); Car(' '); break;
case 3:
Car(sig); Car(cen+'0'); Car(diz+'0'); Car(uni+'0'); Car(' '); break;
} // end switch tyn
break; // case moz 2
case 3: // Compact
switch (tyn) {
case 0:
Car('0'); Car(' '); break;
case 1:
Car(sig); Car(uni+'0'); Car(' '); break;
case 2:
Car(sig); Car(diz+'0'); Car(uni+'0'); Car(' '); break;
case 3:
Car(sig); Car(cen+'0'); Car(diz+'0'); Car(uni+'0'); Car(' '); break;
} // end switch tyn
break; // case moz 3
} // end switch moz
}
#define Dec8(v) \
do { typeof(v) _v = -1; \
if (_v < 0) { Dec8s(v); } \
else { Dec8u(v); } \
} while(0);
void Dec8u (uint8_t hh) {
sig=' ';
BinDec8 (hh); Af3Dig();
}
void Dec8s (int8_t hh) {
if (hh<0) { // négatif
sig='-'; hh = -hh;
} else {
sig='+';
}
BinDec8 (hh); Af3Dig();
}
//-----------------
void BinDec16 (uint32_t bb) {
uni=0;diz=0;cen=0;mil=0;dim=0;
tyn=0; if (bb==0) return;
uni=bb%10; bb=bb/10; if (bb==0){tyn=1;return;}
diz=bb%10; bb=bb/10; if (bb==0){tyn=2;return;}
cen=bb%10; bb=bb/10; if (bb==0){tyn=3;return;}
mil=bb%10; bb=bb/10; if (bb==0){tyn=4;return;}
dim=bb; tyn=5;
}
void Af5Dig() {
switch (moz) {
case 0: // Normal signe devant le nombre
switch (tyn) {
case 0:
Car(' '); Car(' '); Car(' ');Car(' ');Car(' ');Car('0'); Car(' '); break;
case 1:
Car(' '); Car(' '); Car(' ');Car(' ');Car(sig);Car(uni+'0'); Car(' '); break;
case 2:
Car(' '); Car(' '); Car(' ');Car(sig);Car(diz+'0');Car(uni+'0'); Car(' '); break;
case 3:
Car(' '); Car(' '); Car(sig);Car(cen+'0');Car(diz+'0');Car(uni+'0'); Car(' '); break;
case 4:
Car(' '); Car(sig); Car(mil+'0');Car(cen+'0');Car(diz+'0');Car(uni+'0'); Car(' '); break;
case 5:
Car(sig); Car(dim+'0'); Car(mil+'0');Car(cen+'0');Car(diz+'0');Car(uni+'0'); Car(' '); break;
} // end switch tyn
break;
case 1: // Spaces
switch (tyn) {
case 0:
Car(' '); Car(' ');Car(' ');Car(' ');Car(' ');Car('0'); Car(' '); break;
case 1:
Car(sig);Car(' '); Car(' ');Car(' ');Car(' '); Car(uni+'0'); Car(' '); break;
case 2:
Car(sig); Car(' '); Car(' ');Car(' ');Car(diz+'0'); Car(uni+'0'); Car(' '); break;
case 3:
Car(sig); Car(' '); Car(cen+'0'); Car(diz+'0'); Car(uni+'0'); Car(' '); break;
case 4:
Car(sig); Car(' ');Car(mil+'0');Car(cen+'0'); Car(diz+'0'); Car(uni+'0'); Car(' '); break;
case 5:
Car(sig); Car(dim+'0');Car(mil+'0');Car(cen+'0'); Car(diz+'0'); Car(uni+'0'); Car(' '); break;
} // end switch tyn
break; // case 1
case 2: // Zeros
switch (tyn) {
case 0:
Car(' '); Car('0');Car('0');Car('0');Car('0');Car('0'); Car(' '); break;
case 1:
Car(sig); Car('0');Car('0');Car('0'); Car('0'); Car(uni+'0'); Car(' '); break;
case 2:
Car(sig); Car('0');Car('0');Car('0'); Car(diz+'0'); Car(uni+'0'); Car(' '); break;
case 3:
Car(sig); Car('0');Car('0');Car(cen+'0'); Car(diz+'0'); Car(uni+'0'); Car(' '); break;
case 4:
Car(sig); Car('0');Car(mil+'0');Car(cen+'0'); Car(diz+'0'); Car(uni+'0'); Car(' '); break;
case 5:
Car(sig); Car(dim+'0');Car(mil+'0');Car(cen+'0'); Car(diz+'0'); Car(uni+'0'); Car(' '); break;
} // end switch tyn
break;
case 3: // Compact
switch (tyn) {
case 0:
Car('0'); Car(' '); break;
case 1:
Car(sig); Car(uni+'0'); Car(' '); break;
case 2:
Car(sig); Car(diz+'0'); Car(uni+'0'); Car(' '); break;
case 3:
Car(sig); Car(cen+'0'); Car(diz+'0'); Car(uni+'0'); Car(' '); break;
case 4:
Car(sig); Car(mil+'0');Car(cen+'0'); Car(diz+'0'); Car(uni+'0'); Car(' '); break;
case 5:
Car(sig); Car(dim+'0');Car(mil+'0');Car(cen+'0'); Car(diz+'0'); Car(uni+'0'); Car(' '); break;
} // end switch tyn
break;
} // end switch moz
}
#define Dec16(v) \
do { typeof(v) _v = -1; \
if (_v < 0) { Dec16s(v); } \
else { Dec16u(v); } \
} while(0);
void Dec16u (uint16_t hh) {
sig=' ';
BinDec16(hh); Af5Dig();
}
void Dec16s (int16_t hh) {
if (hh<0) { // négatif
sig='-'; hh = -hh;
} else {
sig='+';
}
BinDec16(hh); Af5Dig();
}
// end code
Loading…
Cancel
Save