Reading bit by bit out of bytes - simplification/speed-up suggestions - Delphi

1k views Asked by At

I have a device that sends couple bytes of info about its status, and the first 5 bytes are statuses of 40 pushbuttons. Each bit represents one button, being 1 for released and 0 for pressed.

From that matter, I was doing a checkout using this piece of code:

procedure TForm2.ServerUDPRead(AThread: TIdUDPListenerThread;
  AData: array of Byte; ABinding: TIdSocketHandle);
var received: array [0..4] of string; a1, a2 integer;
bits: array [0..40] of boolean;
begin

for a1 := 0 to 4 do
  Received[a1] := (ByteToBin(AData[a1]));

for a1 := 4 downto 0 do
  begin
    for a2 := 1 to 8 do
      begin
        if Copy(Received[a1], a2, 1) = '0' then bits[(4-a1)*8+(a2-1)]:=False else bits[(4-a1)*8+(a2-1)]:=True;
      end;
  end;

ByteToBin being function for coverting byte to string of 8 bits...

Is there an alternate "easier", simplified and (what I'm actually interested in) faster procedure for achieving what I need, or is this way good enough?

I find it a bit sluggish and dirty... :/ (although ultimately, does it's intention... so interested mostly out of learning point of view)

2

There are 2 answers

1
Tom Brunberg On BEST ANSWER

With this you an convert directly from AData to array of boolean:

for i := 0 to 39 do
  bits[i] :=  (AData[i div 8] and (1 shl (i mod 8))) <> 0;

I'm not sure if the order of the booleans is exactly the same, I lost count with all your indexes :)

3
Uwe Raabe On

An alternative approach is using a set:

type
  TByteSet = set of 0..7;
...
  for I := 0 to 39 do begin
    bits[I] := (I mod 8) in TByteSet(AData[I div 8]);
  end;