Dzień dobry.
Jestem w posiadaniu drukarki posnet thermal. Aby coś wydrukować należy wysłać po RS-ie odpowiednie dane. Cały problem w tym, że wymagane jest coś takiego jak bajt kontrolny, a ja za nic nie wiem jak go obliczyć. Znalazłem instrukcję programisty w której pisze:
Większość sekwencji jest uzupełniona dwoma znakami ('cc') - cyframi HEX (znaki ze zbioru: '0'..'9', 'A'..'F'), które wyrażają w zapisie heksadecymalnym wartość bajtu kontrolnego liczonego dla całej sekwencji w specjalny sposób:
Na początku podstawiamy wartość bajtu kontrolnego:
<byte> := 255;Począwszy od następnego znaku za ESC P obliczamy wartość wyrażenia:
<byte> := <byte> xor <kod danego="danego" znaku="znaku">;
aż do ostatniego znaku sekwencji (nie licząc znaków 'cc' i "końcówki" ESC ).Tak uzyskany bajt kontrolny wyrażamy postaci w cyfr heksadecymalnych i dopisujemy do sekwencji wraz z końcówką 'ESC '.
UWAGA:
Oznaczenie "xor" użyte w procedurze oznacza funkcję logiczną Exclusive Or czyli: ”lub wykluczające”, inaczej zwane "albo". Funkcja ta działa na pojedynczych bitach bajtu. Dla bitów o różnych wartościach wynosi 1, a dla takich samych - 0. Jeśli w użytkowanym przez Państwa języku programowania brakuje funkcji xor, to można ją zdefiniować następująco:
xor (a,b) := (( not a) and b) or (( not b) and a).
Oczywiście użycie nawiasów nie jest tu konieczne ze względu na przestrzeganą chyba we wszystkich językach siłę wiązania poszczególnych funkcji.
Cyfry kontrolne obliczane w ten sposób dają dobre zabezpieczenie przed przekłamaniami transmisji. Przykładowa procedura dopisująca te znaki, napisana w języku PASCAL jest pokazana w rozdziale „Ogólne zasady syntaktyki komend.”
Oraz ten właśnie przykład:
cc - bajt kontrolny, zakodowany jako 2 cyfry HEX (EXOR wszystkich znaków za ESC P do tego bajtu z wartością początkową = #255), dokładnie według następującego algorytmu w języku PASCAL:
begin
check := 255;
for i:= 3 to length(sekwencja)-4 do
check := check xor byte(sekwencja[i]);
end;
Z powyższego wynika, że do kontroli sekwencji nie bierzemy 2 pierwszych znaków (ESC P) oraz 4-ch ostatnich (2 znaki kodujące bajt kontrolny oraz terminator sekwencji ESC ),
UWAGA :
- Obliczoną w powyższej pętli liczbę check stanowiącą wartość bajtu kontrolnego należy przekodować na 2 znaki HEX (znaki ASCII ze zbioru: '0'..'9','A'..'F','a'..'f'), np. korzystając z poniższej funkcji byte_to_hex:
{ *** konwersja liczby na string 'hex' *** }
function word_to_hex (w: word) : string;
var
i : integer;
s : string;
b : byte;
c : char;
begin
s := '';
for i:= 0 to 3 do
begin
b := (hi(w) shr 4) and 15;
case b of
0..9 : c := char(b+$30);
10..15 : c := char(b+$41-10);
end;
s := s + c;
w := w shl 4;
end;
word_ to_hex := s;
end;
{*** konwersja bajtu na 2 znaki ***}
function byte_to_hex (b:byte) : string;
begin
byte_to_hex := copy(word_to_hex(word(b)),3,2);
end;
Niestety mimo pewnych prób nic z tego nie wychodzi. Jestem raczej elektronikiem niż informatykiem, ale musiałem się tego podjąć.
Wiadomo np, że dobrą sekwencją jest:
&1BP1;0$lMoje&0D1&0DA/0.01/0.01/0/E0&1B\
Bajtem kontrolnym jest tu E0
&1B to znak ESC a &0D to Carriage Return (CR). Wiem też również, że liczby 0.01 nie biorą raczej udziału w tym algorytmie, ponieważ gdy je zmieniam to drukarki nie wyrzuca żadnego błędu i drukuje bez problemu.
Ma ktoś może jakiś pomysł jak powinien wyglądać taki algorytm?
s := '1;0$e21S'#13'28.29/28.29/';
abrakadaber