parent
4766e4cf75
commit
e3a10e9eb9
@ -1,3 +1,30 @@
|
||||
# TerSer
|
||||
|
||||
A much smaller and more efficient serial library than Arduinos Serial.
|
||||
Use an include file to replace the Serial.print from Arduino library.
|
||||
|
||||
|
||||
## 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.
|
||||
|
||||
Also when Serial debugging is used to display sensor values, as shown next, suppressing non significative zeros is not adequate for tabular data, specially when the screen is scrolling.
|
||||
Serial.print is a good example of the "Law of instrument":
|
||||
One just uses a bad but widely available tool, and is not willing to find or invent a better one.
|
||||
|
||||
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.
|
||||
|
||||
## Example comparison between Didel TerSer and Arduino Serial
|
||||
| TerSer | Output TerSer | Output Serial | Arduino Serial |
|
||||
| ------------- | ------------- | ------------- | ------------- |
|
||||
| Car('Z'); | Z | Z | Serial.print('Z'); |
|
||||
| Text("Test"); | Test | Test | Serial.print("Test"); |
|
||||
| Bin16(v16); | 0000010001100000 | 10001100000 | Serial.print(v16,BIN); |
|
||||
| Hex16(v16); | 08c0 | 8c0 | Serial.print(v16,HEX); |
|
||||
| Dec16(v16); | 1120 | 1120 | Serial.print(v16); |
|
||||
| Dec16(v16b); | 0020 or 20 | 20 | Serial.print(v16b); |
|
||||
| Dec16(v16s); | + 20 or +0020 | 20 | Serial.print(v16s); |
|
||||
| Dec16(-v16s); | 20 or -0020 | -20 | Serial.print(-v16s); |
|
||||
|
||||
*uint16_t v16=1120; uint16_t v16b=20; int16_t v16s=20;*
|
@ -0,0 +1,165 @@
|
||||
// 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));
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,13 @@
|
||||
//TestTerSerEmpty.ino Terminal série et aff nombres
|
||||
|
||||
#include "TerSer.h"
|
||||
|
||||
void setup() {
|
||||
SetupTerSer();
|
||||
}
|
||||
|
||||
|
||||
void loop() {
|
||||
TerText("Empty"); TerCR();
|
||||
|
||||
}
|
@ -0,0 +1,97 @@
|
||||
//TestTerSer.ino Terminal série et aff nombres
|
||||
|
||||
#include "TerSer.h"
|
||||
#define Serialprint(v,BIN) TerBin8(v)
|
||||
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();
|
||||
}
|
||||
}
|
||||
/*
|
||||
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
|
||||
*/
|
Loading…
Reference in new issue