INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.

Antwort schreiben 
 
Themabewertung:
  • 0 Bewertungen - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
[Vorstellung] Erweiterte Printroutinen
08.01.2019, 14:23 (Dieser Beitrag wurde zuletzt bearbeitet: 08.01.2019 14:24 von Tommy56.)
Beitrag #1
[Vorstellung] Erweiterte Printroutinen
Angeregt durch diesen Thread habe ich mich mit einigen Routinen beschäftigt, die erweiterte Printausgaben ermöglichen.
Als Ziel sind alle Kinder von Stream geeignet, also Serial, lcd, ....
Die Funktionen sind die bitweise Ausgabe aufgefüllt mit führenden 0-Bits für BCD-Einzelbytes und von Ganzzahlen im Bereich von (u)int8_t bis (u)int64_t.
Zusätzlich gibt es Ausgaberoutinen für (u)int64_t Zahlen, die die IDE zwar unterstützt, die aber nicht von print unterstützt werden.
Das ganze ist in ein kleine Lib gepackt (die nur aus einer Headerdatei besteht).

binOut.h:
Code:
/********************************************************************************​****
Copyright (c) 2019 Thomas Kühnert. All rights reserved.

This file is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.
********************************************************************************​*****
Diese Lib beinhaltet einige ergänzende Routinen für die Ausgabe von Ganzzahlen,
die in dieser Form vom print nicht angeboten werden.
Sie können mit allen Schnittstellen genutzt werden, die Nachfahren von Stream sind.
z.B. Serial, SoftwareSerial, LCD, ... die also die Methode print kennen.
********************************************************************************​*****/
#ifndef _BIN_OUT
#define _BIN_OUT

// 4 Bit Ausgabe mit führenden Nullen für Bytes mit BCD-Inhalt.
// Parameter: st = Stream
// Parameter:  b = auszugebendes Byte
void printBcdBin(Stream &st, byte b) {
byte filter = B1000, idx;
  for (byte i=0; i<4;i++) {
    st.print((b & filter)? '1':'0');
    filter >>= 1;
  }  
}

// mit abschließenden LF
void printlnBcdBin(Stream &st, byte b) {
  printBcdBin(st,b);
  st.println();
}

// Ausgabe von (u)int64_t (long long) - sollte nur dafür benutzt werden, obwohl auch die anderen Typen dargestellt werden
// Parameter:   st = Stream
// Parameter: wert = auszugebender Wert int64_t/uint64_t
// Parameter: type = Ausgabetyp (DEC,BIN,HEX) - Default: DEC
template <class T> void printInt64(Stream &st, const T &wert, byte type=DEC) {
uint32_t high, low;
  high = wert >> 32;
  low = wert & 0xFFFFFFFF;
  if (high) st.print(high,type);
  st.print(low,type);
}  

// mit abschließenden LF
template <class T> void printlnInt64(Stream &st, const T &wert, byte type=DEC) {
  printInt64(st,wert,type);
  st.println();
}  

// Binärausgabe einer Ganzzahl von (u)int8_t bis (u)int64_t links aufgefüllt mit 0-Bits
// Parameter:        st = Stream
// Parameter:      wert = auszugebender Wert
// Parameter:    before = Tect, der vor den Bits ausgegeben werden soll - Default: leer
// Parameter: withBlank = Lehrzeichen nach jedem 4.Bit (true/false) Default: false
template <class T> void printBin(Stream &st, const T &wert, const char *before = "", bool withBlank = false) {
byte len = 8 * sizeof(wert);
uint64_t filter = 1;
  filter <<= len - 1;
  if (before) st.print(before);
  for(byte i=0;i<len;i++) {
    if (withBlank && i>0 && i%4 == 0) st.print(' ');
    st.print((wert & filter)? '1':'0');
    filter >>= 1;
  }  
}

// mit abschließenden LF
template <class T> void printlnBin(Stream &st, const T &wert, const char *before = "", bool withBlank = false) {
  printBin(st, wert, before, withBlank);
  st.println();
}
#endif

testBinOut.ino:
Code:
#include <binOut.h>

void setup() {
  Serial.begin(115200);
  Serial.println("Start");
  byte b = 0x03;
  uint16_t i=0x8103;
  uint32_t l=0x81035021;
  uint64_t ll=0x8103502181035021;
  printlnBcdBin(Serial,b);
  printlnBin(Serial,b);
  printlnBin(Serial,i,"Int   B",true);
  printlnBin(Serial,l,"Long  B",true);
  printlnBin(Serial,ll,"LLONG B",true);
  
  printlnInt64(Serial,ll,HEX);
  printlnInt64(Serial,ll);
}

void loop() {}

Evtl. kann jemand bei der Fehlersuche damit etwas anfangen.

Gruß Tommy


Angehängte Datei(en)
.zip  binOut.zip (Größe: 1,83 KB / Downloads: 134)

"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
19.02.2019, 18:33
Beitrag #2
RE: [Vorstellung] Erweiterte Printroutinen
Hallo Tommy,

Ein dankbares Doppel-Uff dafür. Eine ganz einfache Möglichkeit für eine simple Idee. Ich werde meinen Ursprungsgedanken verwerfen. Keine Bits auf dem Display. Schöner Wohnen ist gut, aber nicht um jeden Preis. Ich danke Dir.

Gruß, Anton.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
09.01.2021, 17:40
Beitrag #3
RE: [Vorstellung] Erweiterte Printroutinen
Aus aktuellem Anlass habe ich die Routinen überarbeitet.
Sie liefern jetzt die Bytes zurück, die ausgegebewn wurden, wie das für print üblich ist.
Ergänzt habe ich eine linksbündig bis zur Größe des Datentyps mit 0 aufgefüllte Ausgabe im Hexformat.

binOut.h
Code:
/********************************************************************************​​****
Copyright (c) 2019 Thomas Kühnert. All rights reserved.

This file is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.
********************************************************************************​​*****
Diese Lib beinhaltet einige ergänzende Routinen für die Ausgabe von Ganzzahlen,
die in dieser Form vom print nicht angeboten werden.
Sie können mit allen Schnittstellen genutzt werden, die Nachfahren von Stream sind.
z.B. Serial, SoftwareSerial, LCD, ... die also die Methode print kennen.
********************************************************************************​​*****/
#pragma once

// 4 Bit Ausgabe mit führenden Nullen für Bytes mit BCD-Inhalt.
// Parameter: st = Stream
// Parameter:  b = auszugebendes Byte
size_t printBcdBin(Stream &st, byte b) {
size_t count = 0;
byte filter = B1000;
  for (byte i=0; i<4;i++) {
    count += st.print((b & filter)? '1':'0');
    filter >>= 1;
  }  
  return count;
}

// mit abschließenden LF
size_t printlnBcdBin(Stream &st, byte b) {
size_t count = 0;
  count += printBcdBin(st,b);
  count += st.println();
  return count;
}

// Ausgabe von (u)int64_t (long long) - sollte nur dafür benutzt werden, obwohl auch die anderen Typen dargestellt werden
// Parameter:   st = Stream
// Parameter: wert = auszugebender Wert int64_t/uint64_t
// Parameter: type = Ausgabetyp (DEC,BIN,HEX) - Default: DEC
template <class T> size_t printInt64(Stream &st, const T &wert, byte type=DEC) {
size_t count = 0;
uint32_t high, low;
  high = wert >> 32;
  low = wert & 0xFFFFFFFF;
  if (high) count += st.print(high,type);
  count += st.print(low,type);
  return count;
}  

// mit abschließenden LF
template <class T> size_t printlnInt64(Stream &st, const T &wert, byte type=DEC) {
size_t count = 0;
  count += printInt64(st,wert,type);
  count += st.println();
  return count;
}  

// Binärausgabe einer Ganzzahl von (u)int8_t bis (u)int64_t links aufgefüllt mit 0-Bits
// Parameter:        st = Stream
// Parameter:      wert = auszugebender Wert
// Parameter:    before = Text, der vor den Bits ausgegeben werden soll - Default: leer
// Parameter: withBlank = Lehrzeichen nach jedem 4.Bit (true/false) Default: false
template <class T> size_t printBin(Stream &st, const T &wert, const char *before = "", bool withBlank = false) {
size_t count = 0;
byte len = 8 * sizeof(wert);
uint64_t filter = 1;
  filter <<= len - 1;
  if (before) st.print(before);
  for(byte i=0;i<len;i++) {
    if (withBlank && i>0 && i%4 == 0) count += st.print(' ');
    count += st.print((wert & filter)? '1':'0');
    filter >>= 1;
  }  
  return count;
}

// mit abschließenden LF
template <class T> size_t  printlnBin(Stream &st, const T &wert, const char *before = "", bool withBlank = false) {
size_t count = 0;
  count += printBin(st, wert, before, withBlank);
  count += st.println();
  return count;
}

// Hexärausgabe einer Ganzzahl von (u)int8_t bis (u)int64_t links aufgefüllt mit 0-Nibbles
// Parameter:        st = Stream
// Parameter:      wert = auszugebender Wert
// Parameter:    before = Text, der vor den Bits ausgegeben werden soll - Default: leer
template <class T>  size_t printHex(Stream &st, const T &wert, const char *before = nullptr) {
  size_t count = 0;
  uint8_t len = sizeof(wert)*2;
  char puffer[len+1]; // max. longlong = 8 * 3 + '\0'
  memset(puffer,0,sizeof(puffer));
  uint8_t nibble;
  T aktVal;
  // keine negativen Zahlen und max. 8 Byte groß
  if (wert < 0 || len > 16) {
    count =  st.print("Error");
    return count;
  }
  aktVal = wert;
  if (before != nullptr) {
    count += st.print(before);
  }
  
  for(int8_t i=len-1;i>=0;i--) {
    nibble = aktVal % 16;
    aktVal = aktVal / 16;
    puffer[i] = (nibble > 9) ? nibble-10+'A' : nibble+'0';
  }
  count = st.print(puffer);
  return count;
}

// mit abschließenden LF
template <class T>  size_t printlnHex(Stream &st, const T &wert, const char *before = nullptr) {
  size_t count = 0;
  count += printHex(st, wert, before);
  count += st.println();
  return count;
}

testBinOut.ino:
Code:
#include <binOut.h>

void setup() {
  Serial.begin(115200);
  Serial.println("Start");
  byte b = 0x03;
  uint16_t i=0x8103;
  uint32_t l=0x81035021;
  uint64_t ll=0x8103502181035021;
  uint8_t b2 = 0x4c;
  uint16_t i1 = 0x82, i2 = 0xffff;
  uint32_t l1 = 0x1234, l2 = 0x561234, l3 = 0x56781234;
  size_t bytes;

  printlnBcdBin(Serial,b);
  printlnBin(Serial,b);
  printlnBin(Serial,i,"Int   B",true);
  printlnBin(Serial,l,"Long  B",true);
  printlnBin(Serial,ll,"LLONG B",true);
  
  printlnInt64(Serial,ll,HEX);
  printlnInt64(Serial,ll);
  
  printlnHex(Serial,b2);
  printlnHex(Serial,i1,"0x");
  printlnHex(Serial,i2);
  printlnHex(Serial,l1,"Long 0x");
  printlnHex(Serial,l2,"Long 0x");
  printlnHex(Serial,l3,"Long 0x");
  printlnHex(Serial,ll);
}

void loop() {}

Gruß Tommy


Angehängte Datei(en)
.zip  binOut.zip (Größe: 2,25 KB / Downloads: 37)

"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
17.01.2021, 15:30
Beitrag #4
RE: [Vorstellung] Erweiterte Printroutinen
Ich habe die Hexausgabe noch um ein wahlweises Leerzeichen nach jedem 4. Zeichen ergänzt.

Gruß Tommy


Angehängte Datei(en)
.zip  binOut.zip (Größe: 2,36 KB / Downloads: 39)

"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
16.02.2021, 14:21
Beitrag #5
RE: [Vorstellung] Erweiterte Printroutinen
In der Dezimalsuagabe der Int64 war noch ein Fehler.

Code:
/********************************************************************************​​****
Copyright (c) 2019-2021 Thomas Kühnert. All rights reserved.

This file is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.
********************************************************************************​​*****
Diese Lib beinhaltet einige ergänzende Routinen für die Ausgabe von Ganzzahlen,
die in dieser Form vom print nicht angeboten werden.
Sie können mit allen Schnittstellen genutzt werden, die Nachfahren von Stream sind.
z.B. Serial, SoftwareSerial, LCD, ... die also die Methode print kennen.
********************************************************************************​​*****/
#pragma once

// 4 Bit Ausgabe mit führenden Nullen für Bytes mit BCD-Inhalt.
// Parameter: st = Stream
// Parameter:  b = auszugebendes Byte
size_t printBcdBin(Stream &st, byte b) {
size_t count = 0;
byte filter = B1000;
  for (byte i=0; i<4;i++) {
    count += st.print((b & filter)? '1':'0');
    filter >>= 1;
  }  
  return count;
}

// mit abschließenden LF
size_t printlnBcdBin(Stream &st, byte b) {
size_t count = 0;
  count += printBcdBin(st,b);
  count += st.println();
  return count;
}


// Binärausgabe einer Ganzzahl von (u)int8_t bis (u)int64_t links aufgefüllt mit 0-Bits
// Parameter:        st = Stream
// Parameter:      wert = auszugebender Wert
// Parameter:    before = Text, der vor den Bits ausgegeben werden soll - Default: leer
// Parameter: withBlank = Lehrzeichen nach jedem 4.Bit (true/false) Default: false
template <class T> size_t printBin(Stream &st, const T &wert, const char *before = "", bool withBlank = false) {
size_t count = 0;
byte len = 8 * sizeof(wert);
uint64_t filter = 1;
  filter <<= len - 1;
  if (before) st.print(before);
  for(byte i=0;i<len;i++) {
    if (withBlank && i>0 && i%4 == 0) count += st.print(' ');
    count += st.print((wert & filter)? '1':'0');
    filter >>= 1;
  }  
  return count;
}

// mit abschließenden LF
template <class T> size_t  printlnBin(Stream &st, const T &wert, const char *before = "", bool withBlank = false) {
size_t count = 0;
  count += printBin(st, wert, before, withBlank);
  count += st.println();
  return count;
}

// Hexärausgabe einer Ganzzahl von (u)int8_t bis (u)int64_t links aufgefüllt mit 0-Nibbles
// Parameter:        st = Stream
// Parameter:      wert = auszugebender Wert
// Parameter:    before = Text, der vor den Bits ausgegeben werden soll - Default: leer
// Parameter: withBlank = Lehrzeichen nach jedem 4.Bit (true/false) Default: false
template <class T>  size_t printHex(Stream &st, const T &wert, const char *before = nullptr, bool withBlank = false) {
  size_t count = 0;
  uint8_t len = sizeof(wert)*2;
  char puffer[len+1]; // max. longlong = 8 * 2 + '\0'
  memset(puffer,0,sizeof(puffer));
  uint8_t nibble;
  T aktVal;
  // keine negativen Zahlen und max. 8 Byte groß
  if (wert < 0 || len > 16) {
    count =  st.print("Error");
    return count;
  }
  aktVal = wert;
  if (before != nullptr) {
    count += st.print(before);
  }
  
  for(int8_t i=len-1;i>=0;i--) {
    nibble = aktVal % 16;
    aktVal = aktVal / 16;
    puffer[i] = (nibble > 9) ? nibble-10+'A' : nibble+'0';
  }
  if (withBlank && len>4) {
    byte blankLen = len*3/2;
    char pufBlank[blankLen+1];
    memset(pufBlank,0,sizeof(pufBlank));
    uint8_t z=0;
    for(uint8_t i=0;i<len;i++) {
      pufBlank[z++] = puffer[i];
      if (i && i%4 == 3) {
        pufBlank[z++] = ' ';
      }
    }  
    count = st.print(pufBlank);  
  }
  else count = st.print(puffer);
  return count;
}

// mit abschließenden LF
template <class T>  size_t printlnHex(Stream &st, const T &wert, const char *before = nullptr, bool withBlank = false) {
  size_t count = 0;
  count += printHex(st, wert, before, withBlank);
  count += st.println();
  return count;
}

// Ausgabe von (u)int64_t (long long) - sollte nur dafür benutzt werden, obwohl auch die anderen Typen dargestellt werden
// Parameter:   st = Stream
// Parameter: wert = auszugebender Wert int64_t/uint64_t
// Parameter: type = Ausgabetyp (DEC,BIN,HEX) - Default: DEC
template <class T> size_t printInt64(Stream &st, const T &wert, byte type=DEC) {
  if (type == HEX) return printHex(st,wert);
  if (type == BIN) return printBin(st,wert);
  // DEC
  char puffer[25];
  byte pufLast = sizeof(puffer) -1;
  memset(puffer,'0',sizeof(puffer));
  puffer[pufLast] = '\0';
  T ganz = wert;
  byte rest;
  for(byte i=0;i<pufLast;i++) {
    rest = ganz % 10;
    ganz /= 10;
    puffer[pufLast - i] = rest + '0';
  }
  // vornullen unterdrücken
  byte i=0;
  while (puffer[i++] == '0');
  return st.print(puffer+i-1);
}  

// mit abschließenden LF
template <class T> size_t printlnInt64(Stream &st, const T &wert, byte type=DEC) {
size_t count = 0;
  count += printInt64(st,wert,type);
  count += st.println();
  return count;
}

Gruß Tommy

"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
10.04.2021, 13:28
Beitrag #6
RE: [Vorstellung] Erweiterte Printroutinen
Hier nochmal als Zip.

Gruß Tommy


Angehängte Datei(en)
.zip  binOut.zip (Größe: 2,46 KB / Downloads: 21)

"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste