Byte sum calculation

Pagina: 1
Acties:
  • 128 views sinds 30-01-2008
  • Reageer

  • Mr.Nobody
  • Registratie: Oktober 2001
  • Niet online
Ik ben een programma aan het schrijven in delphi die via de seriele poort communiceert met een apparaat.

nou loop ik tegen een probleem op.

het apparaat reageert niet op mijn commando's. dit komt omdat ik niet weet hoe je de checksum moet berekenen.

de commando's hebben deze structuur:
<STX> <SEQ> <COMMAND> Command name ; Argument 1 ; ... ; Argument n <ETX> <BCC>

<STX> (Refer to ASCII table)
<ETX> (Refer to ASCII table).
<BCC> is a checksum calculated as defined in Appendix.
<SEQ> a command sequence number between 1 and 4 presented in ASCII.
<COMMAND> contains the command name and optional arguments separated by ;
<COMMAND> must be max 2000 characters.

The checksum calculation used is a Byte sum calculation. The received chars between <STX> and <ETX> are summed into a 8 bit variable, any carry produced is re-added into the sum as a least significant bit.

een <COMMAND> is bv: getSampleResultType;1;1
ik neem aan dat je elke keer dat je wat stuurd <SEQ> verhoogt met 1 en na 4 weer begint met 1 :?

welke commando stuur ik nou naar het apparaat?

als iemand een voorbeeld zou willen geven, dan kom ik wel verder. ik heb gezocht met google, maar ik wordt er niet wijs uit.

Opensource delphi componenten (http://www.delphi-jedi.org)


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 15:13
Als het alleen om de checksum gaat, kan ik je wel opweg helpen:
code:
1
2
3
4
5
checksum = 0 
voor alle bytes 'byte':
   checksum = checksum + byte
   if(checksum>256)
    checksum = checksum - 255

Alle bytes zijn dus de bytes tussen STX en ETX, waarbij STX en ETX niet meedoen.

  • Mr.Nobody
  • Registratie: Oktober 2001
  • Niet online
zou je een voorbeeld willen maken met mijn commando?

Opensource delphi componenten (http://www.delphi-jedi.org)


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 15:13
Ik heb niet alle informatie die jij hebt, maar in Java/C/C++ wordt 't zoiets:
code:
1
2
3
4
5
6
7
unsigned char seq[] = {
  2,    /* STX */
  '1',  /* SEQ */
   'g','e','t','S','a','m','p','l','e','R','e','s','u','l','t','T','y','p','e',';','1',';','1',
  3, /* ETX */
  CHECKSUM
}

De checksum is dus op de genoemde manier berekent. Ik neem aan dat SEQ gewoon bij '1' begint (1 to 4 presented in ASCII) en voor elk volgend commando 1 groter wordt (tot '4', daarna weer naar '1').

De STX en ETX karakters zijn ook bytes, maar wat de waardes zijn staat in

Dit alles is puur mijn interpretatie.

  • Mr.Nobody
  • Registratie: Oktober 2001
  • Niet online
dit kwam ik tijdens het googlen tegen:

Var c : char;
b : byte;
i : integer;
r : real;
Begin
c := #i;
b := ord(c);
r := i * 1.0;
i := integer(ord(c));
c := #(byte(trunc(r)));


samen met een andere sourcecode kom ik tot dit:
(form met 1 label en een button, code in onclick en function toegevoegd aan private)


procedure TForm1.Button1Click(Sender: TObject);
var
str:string;
resultaat:byte;
teller:integer;

begin
str := '1getSampleResultType;1;1';
for teller := 0 to length(str) do
begin
resultaat := resultaat + BitLenth(str[teller]);
end;
label1.Caption := inttostr(resultaat);
end;

function TForm1.BitLenth(headers: string):byte;
begin
result := ord(HeaderS[1]);
end;


snappen doe ik het niet en kloppen doet het ook niet, maar goed misschien ben ik wel op de juiste weg?

sjonge zeg, programmeren vindt ik leuk maar deze zooi vindt ik maar nix. en dan nog te weten dat ik ooit TCK gedaan heb :( (das voor de mensen die weten wat het is :) )

Opensource delphi componenten (http://www.delphi-jedi.org)


  • KnoppenSpook
  • Registratie: Augustus 2000
  • Laatst online: 04-09-2023
alles bij elkaar optellen en dan een AND functie toepassen
iets van
opgetelde = opgetelde & 256; (in C)
of opgetelde = opgetelde AND 256;

/me weet geen leuke quote voor in zijn signature


Verwijderd

Op donderdag 14 maart 2002 19:20 schreef Mr.Nobody het volgende:
<STX> <SEQ> <COMMAND> Command name ; Argument 1 ; ... ; Argument n <ETX> <BCC>

The checksum calculation used is a Byte sum calculation. The received chars between <STX> and <ETX> are summed into a 8 bit variable, any carry produced is re-added into the sum as a least significant bit.
In Delphi:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
function GetBCC(Seq: char; Command: string): char;
var
  BCC: Word;
  i: integer;
begin
  BCC := Ord(Seq);
  for i := 1 to Length(Command) do begin
    BCC := BCC + Ord(Command[i]);
    while BCC > $00FF do
    BCC := (BCC and $00FF) + 1;
  end;
  Result := Chr(BCC and $00FF);
end;

Nogal ongebruikelijk checksum algoritme (meestal wordt met XORs gewerkt, en meestal wordt ook de <ETX> nog in de checksum meegenomen), maar door ook de carry flag erin te betrekken kon 't wel 's aardig safe zijn.

Die carry flag betekent in feite gewoon dat het getal groter dan 255 is geworden (vandaar dat ik BCC als Word -2 bytes- heb gedefinieerd), en als dat 't geval is, moet er 1 bij de BCC worden opgeteld, als ik 't goed snap.

Dat 'while' stukje heb ik voor de veiligheid ingebouwd, omdat het optellen van die carry flag er ook weer voor kan zorgen dat BCC groter dan 255 wordt...

  • Mr.Nobody
  • Registratie: Oktober 2001
  • Niet online
bedank allemaal, ik zal er morgens eens mee gaan stoeien. en dan kijken of ik nu wel reactie terug krijg.

Opensource delphi componenten (http://www.delphi-jedi.org)


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 15:13
Succes met het programma, maar wil je in het vervolg:
1) [code] tags gebruiken om je code leesbaar te maken
2) als iemand (hier ik :)) je volledige pseudocode geeft niet gaan smeken om een daadwerkelijke implementatie daarvan? Als je niet kan programmeren hoor je hier niet thuis; wij zijn er niet om jou code te schrijven.

(Code van AfterLife bevat trouwens een overbodige lus).

Verwijderd

Oeps...
Ik denk dat ik "any carry produced is re-added into the sum as a least significant bit" verkeerd geinterpreteerd heb. Hij wordt er niet bij opgeteld, maar die carry (1 dus) WORDT het LSB.

dan wordt 't:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
function GetBCC(Seq: char; Command: string): char;
var
  BCC: Word;
  i: integer;
begin
  BCC := Ord(Seq);
  for i := 1 to Length(Command) do begin
    BCC := BCC + Ord(Command[i]);
    if BCC > $00FF then
    BCC := (BCC and $00FE) + 1;
  end;
  Result := Chr(BCC);
end;

Nou ja, 1 van de 2 zou moeten werken, maar echt duidelijk is die protocol-beschrijving niet...

Verwijderd

Op donderdag 14 maart 2002 22:34 schreef Soultaker het volgende:
(Code van AfterLife bevat trouwens een overbodige lus).
Leg uit? 'k Ben altijd in voor verbeteringen! :)

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 15:13
Op donderdag 14 maart 2002 22:49 schreef Afterlife het volgende:
Leg uit? 'k Ben altijd in voor verbeteringen! :)
Ik doelde op de while-lus (die er in de verbetering uit is). Aangezien een byte maximaal 255 kan zijn, kan de optelling van twee bytes maximaal 510 zijn. 510-256+1 = 255, dus de while lus is overbodig, aangezien je gegarandeerd maximaal één keer je carry bit hoeft op te tellen.
Ik denk trouwens dat jou eerste interpretatie toch de correcte was (hoewel ik inderdaad ook de tweede heb overwogen) en dat komt vooral doordat er over "re-added into the sum" wordt gesproken. Als de carry een bit set, dan is er naar mijn mening geen sprake meer van een optelling, dus zal dat wel niet bedoeld zijn.
Pagina: 1