cs_nitrique
Messages postés344Date d'inscriptionjeudi 1 mai 2003StatutMembreDernière intervention 4 avril 2011
-
31 août 2006 à 10:15
jinh68
Messages postés215Date d'inscriptionmardi 29 juillet 2003StatutMembreDernière intervention 1 septembre 2006
-
1 sept. 2006 à 11:28
Bonjour,
Je récupère des paquets via le port COM que je dois traiter ensuite.
Notament, dans ce paquet, il y a un timestamp sur 4 bytes répartis de cette manière:
seconds (6 bits)
minutes (6 bits)
hours (5 bits)
days (5 bits)
months (4 bits)
years (6 bits)
N'ayant jamais fait ce genre de chose, je vous demande de l'aide.
(Il faut transformer en binaire et recopier la longueur voulue dans un byte en rajoutant des 0 devant, nan ?)
jinh68
Messages postés215Date d'inscriptionmardi 29 juillet 2003StatutMembreDernière intervention 1 septembre 2006 1 sept. 2006 à 09:53
Erf, j'avoue que j'aimerais bien comprendre où merde mon code vu que c'est exactement ce que tu fais linéairement.
Pourrais-tu juste tester rapidement cette unité:
unit ComTimeStamp;
interface
uses
Classes,
Windows,
SysUtils,
Dialogs;
type
{
seconds (6 bits)
minutes (6 bits)
hours (5 bits)
days (5 bits)
months (4 bits)
years (6 bits)
}
TCOMTimeStamp = class
private
FValues: array[0..5] of Dword;
FPacket: DWORD;
procedure GetCOMTimeStampFrom(Packet: DWORD);
function GetValue(indice: integer): DWORD;
function COMTimeStampToStr: string;
public
constructor Create(Packet: Dword);
procedure Display;
published
property Seconds: DWord index 5 read GetValue;
property Minutes: DWord index 4 read GetValue;
property Hours: DWord index 3 read GetValue;
property Days: DWord index 2 read GetValue;
property Months: DWord index 1 read GetValue;
property Years: DWord index 0 read GetValue;
property COMTimeStamp: string read COMTimeStampToStr;
property Packet read FPacket;
end;
implementation
constructor TCOMTimeStamp.Create(Packet: DWord);
begin
GetCOMTimeStampFrom(Packet);
end;
procedure TCOMTimeStamp.GetCOMTimeStampFrom(Packet: DWord);
const ShrValues: array[0..5] of Byte = (6,4,5,5,6,0);
const MaskValues: array[0..5] of Byte = ($3f,$0f,$1f,$1f,$3f,$3f);
var i: integer;
begin
//Sauvegarde
FPacket := Packet;
for i := Low(MaskValues) to High(MaskValues) do
begin
FValues[i] := Packet and MaskValues[i] ;
Packet := Packet shr ShrValues[i];
end;
end;
function TCOMTimeStamp.GetValue(indice: integer):DWORD;
begin
result := FValues[indice];
end;
function TCOMTimeStamp.COMTimeStampToStr: string;
var tag: string;
begin
if Hours < 12 then
tag := 'AM'
else tag := 'PM';
result := (Format('%d:%d:%d %s %d/%d/%.2d', [Hours, Minutes, Seconds,tag, Months, Days,Years]));
end;
procedure TCOMTimeStamp.Display;
begin
ShowMessage(COMTimeStampToStr);
end;
cs_neko
Messages postés135Date d'inscriptionjeudi 14 août 2003StatutMembreDernière intervention12 octobre 20061 31 août 2006 à 13:12
Il n'y a pas besoin de "transformer" en binaire, une valeur entière est toujours représentée en binaire en mémoire.
tu dois te renseigner sur les opératiosn binaires en revanche
( 1 or 1 ) = 1
( 1 or 0 ) = 1
( 0 or 0 ) = 0
( 1 xor 1 ) = 0
( 1 xor 0 ) = 1
( 0 xor 0 ) = 0
( 1 and 1 ) = 1
( 1 and 0 ) = 0
( 0 and 0 ) = 0
//Attention c'est en binaire 1=1, 10=2, 11=3, 100=4, etc...( 100 shr 0 ) 100 ( 1 shl 0 ) 1( 100 shr 1 ) 010 ( 1 shl 1 ) 10( 100 shr 2 ) 001 ( 1 shl 2 ) 100
bon, a supposer que les secondes soient dans les bits de gauche:
0000 0000 0000 0000 0000 0000 0000 0000
function COMTimeStampToString(TimeStamp: Cardinal): String;
Begin
//Years
Result:=IntToStr(TimeStamp And $0000003F) + 'Years, '; // On prend que les 6 derniers bits de la variable et on masque les autres
//Month
Result:=Result+IntToStr((TimeStamp shr 6) And $0000000F)+'Months, ' // Idem, mais avant on décale de 6 bits vers la droite pour virrer l'année
//Day
result:=result+IntToStr((TimeStamp shr 10) And $0000001F)+'Days, ' // Idem mais on décale de 10 ( 6 + 4 )
//etc.
End;
exemple
tes bits ( valeurs au pif ):
1100 1111 0000 1111 1010 1111 1111 0000
And
0000 0000 0000 0000 0011 1111 ( $0000003F en hexa )
=
0000 0000 0000 0000 0000 0000 0011 0000
jinh68
Messages postés215Date d'inscriptionmardi 29 juillet 2003StatutMembreDernière intervention 1 septembre 2006 31 août 2006 à 14:22
Salut,
Un petit exemple:
{
seconds (6 bits)
minutes (6 bits)
hours (5 bits)
days (5 bits)
months (4 bits)
years (6 bits)
}
TCOMTimeStamp = class
private
FValues: array[0..5] of Dword;
FPacket: DWORD;
procedure Display;
procedure GetCOMTimeStampFrom(Packet: DWORD);
function GetValue(indice: integer): DWORD;
public
constructor Create(Packet: Dword);
published
property Seconds: DWord index 0 read GetValue;
property Minutes: DWord index 1 read GetValue;
property Hours: DWord index 2 read GetValue;
property Days: DWord index 3 read GetValue;
property Months: DWord index 4 read GetValue;
property Years: DWord index 5 read GetValue;
end;
constructor TCOMTimeStamp.Create(Packet: DWord);
begin
GetCOMTimeStampFrom(Packet);
end;
procedure TCOMTimeStamp.GetCOMTimeStampFrom(Packet: DWord);
const ShrValues: array[0..5] of Byte = (6,6,5,5,4,0);
const MaskValues: array[0..5] of Byte = ($3f,$3f,$1f,$1f,$0f,$ff);
var i: integer;
begin
//Sauvegarde
FPacket := Packet;
for i := Low(MaskValues) to High(MaskValues) do
begin
FValues[i] := Packet and MaskValues[i] ;
Packet := Packet shr ShrValues[i];
end;
end;
function TCOMTimeStamp.GetValue(indice: integer):DWORD;
begin
result := FValues[indice];
end;
procedure TCOMTimeStamp.Display;
begin
ShowMessage(Format('%d années : %d mois : %d jours : %d heures : %d minutes : %d secondes', [FValues[5],FValues[4],FValues[3],FValues[2],FValues[1],FValues[0]]));
end;
cs_nitrique
Messages postés344Date d'inscriptionjeudi 1 mai 2003StatutMembreDernière intervention 4 avril 20111 31 août 2006 à 15:15
Voici les 4 bits pour 11:28:37 AM 8/31/06: (149)(197)(254)(6)
149 en binaire donne: 10010101
Les 6 premiers bits sont: 100101 et ça fait bien 37 secondes !
J'espère que maVar à cette valeur: 149 197 254 6 (je n'en suis même pas sur...).
En fait, comment affecter le paramètre attendu par ta classe ?
Seulement je n'arrive pas jongler comme ça avec Delphi !
Pour moi les secondes commencent à partir de la droite(donc 6).
Tu pars de l'autre sens toi?(d'ailleurs j'espère parce que les résultats sont aberrants là).
cs_nitrique
Messages postés344Date d'inscriptionjeudi 1 mai 2003StatutMembreDernière intervention 4 avril 20111 31 août 2006 à 15:52
Je récapitule parce que je me perds:
les 4 bytes: (149)(197)(254)(6) doivent donner: 11:28:37 AM 8/31/06. (format americain)
Exemple pour les secondes:
(149)(197)(254)(6) donne:
10010101 11000101 11111110 00000110
Les 6 premiers bits sont: 100101 et ça fait bien 37 secondes
les 6 suivants sont: 011100 donnent bien 28 minutes.
...
C'est ce comportement que je m'efforce de reproduire avec delphi.
C'est tellement simple sur papier !
Déjà, comment les concatener dans un word (est ce que mon for est bon) ?
Ensuite, le découper selon les longueur à extraire ?
cs_nitrique
Messages postés344Date d'inscriptionjeudi 1 mai 2003StatutMembreDernière intervention 4 avril 20111 31 août 2006 à 15:56
Déjà, mon for n'est pas bon vu que ça me retourne
2512780806 au lieu de
2504610384
Voici ma boucle:
MaVar := 0;
for j := 0 to 3 do begin
MaVar := MaVar+LongWord(tampon[nblu-4+j-3]) shl (j*8);
end;
NbLue C'est la quantité de bytes dans le paquet, le timestamp commence à l'incide NbLue-4.
(Le paquet à une longueur variable et il y a d'autres données avant le timestamp).
jinh68
Messages postés215Date d'inscriptionmardi 29 juillet 2003StatutMembreDernière intervention 1 septembre 2006 31 août 2006 à 16:11
Voici l'unit corrigée:
unit ComTimeStamp;
interface
uses
Classes,
Windows,
SysUtils,
Dialogs;
type
{
seconds (6 bits)
minutes (6 bits)
hours (5 bits)
days (5 bits)
months (4 bits)
years (6 bits)
}
TCOMTimeStamp = class
private
FValues: array[0..5] of Dword;
FPacket: DWORD;
procedure GetCOMTimeStampFrom(Packet: DWORD);
function GetValue(indice: integer): DWORD;
public
constructor Create(Packet: Dword);
procedure Display;
published
property Seconds: DWord index 5 read GetValue;
property Minutes: DWord index 4 read GetValue;
property Hours: DWord index 3 read GetValue;
property Days: DWord index 2 read GetValue;
property Months: DWord index 1 read GetValue;
property Years: DWord index 0 read GetValue;
end;
implementation
constructor TCOMTimeStamp.Create(Packet: DWord);
begin
GetCOMTimeStampFrom(Packet);
end;
procedure TCOMTimeStamp.GetCOMTimeStampFrom(Packet: DWord);
const ShrValues: array[0..5] of Byte = (6,4,5,5,6,0);
const MaskValues: array[0..5] of Byte = ($3f,$0f,$1f,$1f,$3f,$ff);
var i: integer;
begin
//Sauvegarde
FPacket := Packet;
for i := Low(MaskValues) to High(MaskValues) do
begin
FValues[i] := Packet and MaskValues[i] ;
Packet := Packet shr ShrValues[i];
end;
end;
function TCOMTimeStamp.GetValue(indice: integer):DWORD;
begin
result := FValues[indice];
end;
procedure TCOMTimeStamp.Display;
var tag: string;
begin
if Hours < 12 then
tag := 'AM'
else tag := 'PM';
ShowMessage(Format('%d:%d:%d %s %d/%d/%.2d', [Hours,Minutes,Seconds,tag ,Months,Days,Years]));
end;
jinh68
Messages postés215Date d'inscriptionmardi 29 juillet 2003StatutMembreDernière intervention 1 septembre 2006 31 août 2006 à 16:23
En fait la finale:
unit ComTimeStamp;
interface
uses
Classes,
Windows,
SysUtils,
Dialogs;
type
{
seconds (6 bits)
minutes (6 bits)
hours (5 bits)
days (5 bits)
months (4 bits)
years (6 bits)
}
TCOMTimeStamp = class
private
FValues: array[0..5] of Dword;
FPacket: DWORD;
procedure GetCOMTimeStampFrom(Packet: DWORD);
function GetValue(indice: integer): DWORD;
function COMTimeStampToStr: string;
public
constructor Create(Packet: Dword);
procedure Display;
published
property Seconds: DWord index 5 read GetValue;
property Minutes: DWord index 4 read GetValue;
property Hours: DWord index 3 read GetValue;
property Days: DWord index 2 read GetValue;
property Months: DWord index 1 read GetValue;
property Years: DWord index 0 read GetValue;
property COMTimeStamp: string read COMTimeStampToStr;
property Packet read FPacket;
end;
implementation
constructor TCOMTimeStamp.Create(Packet: DWord);
begin
GetCOMTimeStampFrom(Packet);
end;
procedure TCOMTimeStamp.GetCOMTimeStampFrom(Packet: DWord);
const ShrValues: array[0..5] of Byte = (6,4,5,5,6,0);
const MaskValues: array[0..5] of Byte = ($3f,$0f,$1f,$1f,$3f,$ff);
var i: integer;
begin
//Sauvegarde
FPacket := Packet;
for i := Low(MaskValues) to High(MaskValues) do
begin
FValues[i] := Packet and MaskValues[i] ;
Packet := Packet shr ShrValues[i];
end;
end;
function TCOMTimeStamp.GetValue(indice: integer):DWORD;
begin
result := FValues[indice];
end;
function TCOMTimeStamp.COMTimeStampToStr: string;
var tag: string;
begin
if Hours < 12 then
tag := 'AM'
else tag := 'PM';
result := (Format('%d:%d:%d %s %d/%d/%.2d', [Hours, Minutes, Seconds,tag, Months, Days,Years]));
end;
procedure TCOMTimeStamp.Display;
begin
ShowMessage(COMTimeStampToStr);
end;