Dump obsahu premennej na sériový port

Sekcia určená pre Arduino nadšencov

Moderátor: Moderátori

Používateľov profilový obrázok
roboulbricht
Stály člen
Stály člen
Príspevky: 156
Dátum registrácie: 07 Jan 2015, 12:01
Bydlisko: Banská Bystrica
Vek: 54
Kontaktovať používateľa:

Dump obsahu premennej na sériový port

Príspevok od používateľa roboulbricht » 23 Okt 2016, 22:10

Každý si občas vypíše obsah premennej na sériový port, keď je niekde chyba a nevieme kde. Táto sada šablónových funkcii a makier to značne uľahčí.

Kód

Kód: Vybrať všetko

template< typename T > void dumpHex(T &t) {
  int       theValue;
  char      textString[16];
  char      asciiDump[16];
  const uint8_t *myAddressPointer = (uint8_t*) &t;
  int mySize = sizeof(t);
  int maxrow;

  while (mySize > 0) {
    maxrow = min(16, mySize);
    sprintf(textString, "%04X - ", myAddressPointer);
    Serial.print(textString);
    asciiDump[0]    = 0;
    for (int ii = 0; ii < maxrow; ii++) {
      theValue  = *myAddressPointer;
      sprintf(textString, "%02X ", theValue);
      Serial.print(textString);
      if ((theValue >= 0x20) && (theValue < 0x7f))
        asciiDump[ii]  = theValue;
      else
        asciiDump[ii]  = '.';
      myAddressPointer++;
    }
    asciiDump[maxrow] = 0;
    Serial.println(asciiDump);
    mySize -= maxrow;
  }
}

uint8_t sensorAdress[2][8] = {{ 0x28, 0xFF, 0x4E, 0xB8, 0x92, 0x15, 0x1, 0xA4 },
  { 0x28, 0xFF, 0x42, 0xB8, 0x92, 0x15, 0x1, 0x85 },
};

int abc=123;
double xyz=1.;
long qwe=4456789L;
const char mytext[]="ja som text 01234567890123456789";
uint8_t ttt='t';

#define DUMPVAL(var)     \
 {                       \ 
 Serial.print("Dump: "); \
 Serial.print(#var);     \
 Serial.print("=");      \
 Serial.println(var);    \
 dumpHex(var);           \
 }

#define DUMP(var)        \
 {                       \ 
 Serial.print("Dump: "); \
 Serial.println(#var);   \
 dumpHex(var);           \
 }

void setup() {
  Serial.begin(9600);
  DUMPVAL(abc);
  DUMPVAL(xyz);
  DUMPVAL(qwe);
  DUMP(sensorAdress);
  DUMPVAL(mytext);
  DUMPVAL(ttt);

  for(int i=0;i<3;i++)
    DUMPVAL(i); 
}

void loop() {
}
Výstup

Kód: Vybrať všetko

Dump: abc=123
0119 - 7B 00 {.
Dump: xyz=1.00
0115 - 00 00 80 3F ...?
Dump: qwe=4456789
0111 - 55 01 44 00 U.D.
Dump: sensorAdress
0101 - 28 FF 4E B8 92 15 01 A4 28 FF 42 B8 92 15 01 85 (.N.....(.B.....
Dump: mytext=ja som text 01234567890123456789
012B - 6A 61 20 73 6F 6D 20 74 65 78 74 20 30 31 32 33 ja som text 0123
013B - 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 4567890123456789
014B - 00 .
Dump: ttt=116
0100 - 74 t
Dump: i=0
08D9 - 00 00 ..
Dump: i=1
08D9 - 01 00 ..
Dump: i=2
08D9 - 02 00 ..
0

Používateľov profilový obrázok
roboulbricht
Stály člen
Stály člen
Príspevky: 156
Dátum registrácie: 07 Jan 2015, 12:01
Bydlisko: Banská Bystrica
Vek: 54
Kontaktovať používateľa:

Re: Dump obsahu premennej na sériový port

Príspevok od používateľa roboulbricht » 13 Apr 2020, 17:26

Ukážka ďalších šablón, ktoré vedia uľahčiť výpisy premenných na sériový port. Pomocou jednoduchej šablónovej funkcie si môžete zreťaziť vypisovanie obsahu premenných do podoby, ako je obvyklé v c++ v objektoch std::cout.

Kód: Vybrať všetko

template<class T> inline Print& operator <<(Print &obj, T arg) {
  obj.print(arg);
  return obj;
}

template<> inline Print& operator <<(Print &obj, float arg) {
  obj.print(arg, 3);
  return obj;
}

int cnt = 0;

void setup() {
  Serial.begin(9600);
  Serial << "Simple Template Print\n";
}

void loop() {
  float rnd = random(100000) / 10000.;
  String original(rnd);
  Serial << "Loop: " << cnt << ", " << rnd << " (" << original << ")\n";
  cnt++;
  delay(2000);
}
Vyhnete sa tak nekonečnému používaniu sérií Serial.print(premenná);, keď chcete toho na riadok vypísať trochu viac. Volanie tých funkcií tam síce je skryté v tele šablóny, ale to už vás nemusí trápiť, pretože o vytvorenie jednotlivých funkcií zo šablóny podľa parametra sa postará kompilátor. Výsledok v tvare Serial << "Loop: " << cnt << ", " << rnd << " (" << original << ")\n"; za to určite stojí. Jednoduché a prehľadné. Pri dlhších programoch s väčším množstvom výpisov je úspora výrazná.

https://www.arduinoslovakia.eu/blog/202 ... riovy-port
https://github.com/RoboUlbricht/arduino ... late_print
https://en.cppreference.com/w/cpp/io/cout
0

Používateľov profilový obrázok
roboulbricht
Stály člen
Stály člen
Príspevky: 156
Dátum registrácie: 07 Jan 2015, 12:01
Bydlisko: Banská Bystrica
Vek: 54
Kontaktovať používateľa:

Re: Dump obsahu premennej na sériový port

Príspevok od používateľa roboulbricht » 29 Máj 2020, 08:27

Ďalšia sada tried, makier a funkcií, tentoraz zameraná na obsah jednotlivých bitov v registroch.

https://www.arduinoslovakia.eu/blog/202 ... kontrolera

Definície

Kód: Vybrať všetko

#define RESERVED -1

class DumpRegister {
    int reg;
    const char *regname;
    int bits[8];
    const char *bitnames[8];

  public:
    DumpRegister(int _reg, const char *_regname,
                 int b7, int b6, int b5, int b4, int b3, int b2, int b1, int b0,
                 const char *bn7, const char *bn6, const char *bn5, const char *bn4,
                 const char *bn3, const char *bn2, const char *bn1, const char *bn0)
      : reg(_reg),
        regname(_regname)
    {
      bits[7] = b7; bitnames[7] = bn7;
      bits[6] = b6; bitnames[6] = bn6;
      bits[5] = b5; bitnames[5] = bn5;
      bits[4] = b4; bitnames[4] = bn4;
      bits[3] = b3; bitnames[3] = bn3;
      bits[2] = b2; bitnames[2] = bn2;
      bits[1] = b1; bitnames[1] = bn1;
      bits[0] = b0; bitnames[0] = bn0;
    }

    friend Print& operator << (Print &obj, DumpRegister &d);
};

Print& operator << (Print &obj, DumpRegister &d) {
  obj.print(d.regname);
  obj.print("=");
  int v = *(volatile uint8_t *)(d.reg);
  obj.print(v, BIN);
  obj.print(":");
  for (int i = 7; i >= 0; i--)
    if (d.bits[i] != -1 && v & (1 << i)) {
      obj.print(" ");
      obj.print(d.bitnames[i]);
    }
  obj.println("");
  return obj;
}

#define DREG(var, b7, b6, b5, b4, b3, b2, b1, b0) \
  DumpRegister dr_##var(&var, #var, b7, b6, b5, b4, b3, b2, b1, b0, #b7, #b6, #b5, #b4, #b3, #b2, #b1, #b0);

#define _(var) dr_##var

#define DUMPVAL(var)          \
  {                           \
    Serial.print(#var);       \
    Serial.print("=");        \
    Serial.println(var, BIN); \
  }
A použitie.

Kód: Vybrať všetko

DREG(TCCR2A, COM2A1, COM2A0, COM2B1, COM2B0, RESERVED, RESERVED, WGM21, WGM20)
DREG(TCCR2B, FOC2A, FOC2B, RESERVED, RESERVED, WGM22, CS22, CS21, CS20)
DREG(TCCR1A, COM1A1, COM1A0, COM1B1, COM1B0, RESERVED, RESERVED, WGM11, WGM10)
DREG(TCCR1B, FOC1A, FOC1B, RESERVED, RESERVED, WGM12, CS12, CS11, CS10)

void setup() {
  pinMode(11, OUTPUT); // TIMER2A
  pinMode(9, OUTPUT);  // TIMER1A
  analogWrite(11, 1);  // minimal PWM value
  analogWrite(9, 1);   // minimal PWM value

  Serial.begin(9600);
  Serial.println("PWM modes");

  // TIMER2
  Serial << _(TCCR2A);
  Serial << _(TCCR2B);
  DUMPVAL(OCR2A)
  DUMPVAL(OCR2B)
  
  // TIMER1
  Serial << _(TCCR1A);
  Serial << _(TCCR1B);
  DUMPVAL(OCR1A)
  DUMPVAL(OCR1B)
}

void loop() {
}
0

Napísať odpoveď
  • Podobné témy
    Odpovedí
    Zobrazení
    Posledný príspevok