nochmal Packed ASCII



  • HART makes limited use of data compression in the form of Packed ASCII. Normally, there are 256 possible ASCII characters, so that a full byte is needed to represent a character. Packed ASCII is a subset of full ASCII and uses only 64 of the 256 possible characters. These 64 characters are the capitalized alphabet, numbers 0 through 9, and a few punctuation marks. Many HART parameters need only this limited ASCII set, which means that data can be compressed to 3/4 of normal. This improves transmission speed, especially if the textual parameter being communicated is a large one.

    Since only full bytes can be transmitted, the 3/4 compression is fully realized only when the number of uncompressed bytes is a multiple of 4. Any fractional part requires a whole byte. Thus, if U is the number of uncompressed bytes, and T the number of transmitted bytes; find T = (3*U)/4 and increase any fractional part to 1. As examples, U = 3, 7, 8, and 9 result in T = 3, 6, 6, and 7.

    The rule for converting from ASCII to Packed ASCII is just to remove bits 6 and 7 (two most significant). An example is the character "M". The full binary code to represent this is 0100,1101. The packed binary code is 00,1101. The rules for conversion from packed ASCII back to ASCII are (1) set bit 7 = 0 and (2) set bit 6 = complement of packed ASCII bit 5.

    Note that, with some exceptions, HART Slaves don't need to do the compression or know anything about the compression. They simply store and re-transmit the already compressed data. Again, this is an instance where the more difficult software is placed in the device (Master) that is more capable of dealing with it.

    um nun den String ABCD darzustellen, sendet mir ein Messgerät:
    0x04 0x20 0xC4.

    Diese Hexdezimalen Werte stelle ich nun binär dar:
    00000100 00100000 11000100

    Nun teile ich sie in 4 Segment zu je 6Bit auf:
    000001 000010 000011 000100

    Nun wieder auf 8Bit-Länge bringen mit der Regel(set bit 7 = 0 and (2) set bit 6 = complement of packed ASCII bit 5.):
    01000001 01000010 01000011 01000100

    Nun in der ASCII-Tabelle nachschauen und das Ergebnis ist: ABCD

    Mir fehlt jetzt noch eine Methode, in VC++, die genau das für mich macht.
    Hat jemand eine Idee wie man sowas elegant lösen kann?



  • Du kannst die vier Bytes in eine 'unsigned long' Variable einlesen und mit Bit-Operatoren (&,|,>>) auseinandernehmen:

    //Achtung: ungetestet
    unsigned long packed;
    read(device,&packed,3);
    char unpacked[5]={0};
    for(int i=0;i<4;++i)
    {
      unpacked[i]=packed>>(6*(3-i)) & 0x3F;
      char bit6 = (~unpacked[i] & 0x10) << 1;
      unpacked[i]|=bit6;
    }
    


  • Hmm? So ganz kapiere ich ja nicht was du da machst.



  • CStoll schrieb:

    for(int i=0;i<4;++i)
    {
      unpacked[i]=packed>>(6*(3-i)) & 0x3F;   //aufteilen in 6er-Blöcke
      char bit6 = (~unpacked[i] & 0x10) << 1; //"set bit 6 = complement of packed ASCII bit 5.)"
      unpacked[i]|=bit6;                      //bit 6 wird gesetzt (bit 7 wurde von vornherein mit 0 belegt
    }
    

Anmelden zum Antworten