|
Rs232
2400 Bauds
8 bits
N parity
RTS haut,
DTR Bas pour initialiser une commande.
les commandes pour lire sont décrites par
Centauri (cf liens 1iere page)
La transmission par la RS232 se fait sous forme d'échange
d'octets, mais l'adressage pour la station se fait par "nibbles" (ou
1/2 octets).
Donc
Si vous voulez lire un octet à l'adresse 0x1234, l'octet suivant
sera à l'adresse 0x1236.
Si vous voulez lire un nibble à l'adresse 0x1234, le nibble
suivant sera également à l'adresse 0x1234 si l'adresse
est paire.
Si l'adresse est impaire il faudra lire l'octet suivant à
l'adresse 0x1236 et séparer le nibble de l'octet reçu.
Le protocole général est le suivant:
- Initialisation pour être sûr que la
station est disponible
- Envoyer l'adresse sur laquelle on veut passer une
commande
- Envoi de la commande: lecture, écriture,
activation ou désactivation d'un bit
- Lecture des résultats (uniquement si commande
de lecture).
Résumé des commandes:
1. Initialisation
Toute première commande, ou lorsque une erreur est survenue,
pour reprendre la main.
Mettre DTR bas
Mettre RTS Haut
PROG (envoie) STATION (répond)
0x06
0x02
Il est parfois nécessaire de recommencer cette étape
plusieures fois pour reprendre la main.
2. Envoi de l'adresse
L'adressage se fait toujours par l'envoi de 4 octets, octet par octet:
Exemple adresse 0x8: envoyer 0x0008
adresse
0x512: envoyer 0x0512
adresse
0x13B2: envoyer 0x13B2
Mais l'envoi de l'adresse nécessite un codage particulier avec
la valeur 0x82. C'est cette valeur qui permet à la station de
reconnaitre que nous somme en mode adressage.
L'octet à envoyer se calcule par la formule:
0x82+(nibble_de_l'adresse*4)
Exemple:
0x0008 : envoyer 0x82+0*4, puis 0x82+(0*4), puis 0x82+(0*4), puis
0x82+(8*4)
0x0512 : envoyer 0x82+0*4, puis 0x82+(5*4), puis 0x82+(1*4), puis
0x82+(2*4)
0x13B2 : envoyer 0x82+1*4, puis 0x82+(3*4), puis 0x82+(B*4), puis
0x82+(2*4)
Réponse de la station à chaque octet
d'adressage
A chaque envoi d'un octet, en mode
adressage la station répond par un octet. Cela permet de savoir
s'il n'y a pas eu d'erreur soit de transmission soit de
compréhension. En effet un erreur pourrait signifier une fausse
addresse et être dommageable. Il faut donc, à chaque
octet envoyé vérifier la réponse de la
station, et en cas d'erreur refaire aussitôt une
initialisation (paragraphe 1).
L'octet retourné contient dans
son nibble haut, le rang de l'adresse (variant de 0 à 3) et dans
le
nibble bas le nibble en clair.
Exemple:
0x0512: reponse à l'octet 1: 0x00, reponse à l'octet 2:
0x15, reponse à l'octet 3: 0x21 reponse à l'octet 4: 0x32
Pour vérifier l'octet de retour:
return_byte=rang*0x10+int((octet_envoyé-0x82))/4
ou plus simplement
return_byte=rang*0x10+addresse_nibble
3° Commande de lecture.
Le codage de la commande se fait après le choix de l'adresse.
La commande de lecture n'est plus 0x82 mais 0xC2.
La demande se fait en nombre d'octets pas en nombre de nibbles.
On demandera donc de 0 à 0xF octets
La commande est donc:
0xC2+ (nb_octets_demandés*4)
Exemple: lire 3 octets:
0xC2+(3*4)=0xCE
On ne peut pas lire plus de 0xF octets donc la commande ne peut
être supérieure à 0xFE
Réponse de la station à la commande de
lecture
La station ne répond pas 0x4N comme on pourrait le penser mais
0x3N
Exemple 2 0ctets: réponse 0x32
Dans la formule précédente le rang reste 3
Lecture des octets demandés
Immédiatement aprés l'acquiescement à la commande
de lecture, la station retourne les octets demandés, suivis d'un
octet de cheksum. et est prête pour recevoir une autre adresse,
sans reinitialisation. Par contre il faut s'assurer que DTR et RTS sont
toujours bas et hauts. Le cheksum ne comprenant qu'un octet, on
éliminera dans son calcul la partie > 0xFF.
Cartographie de la mémoire:
Les adresses 0x0000 à 0x01FF sont utilisées pour le
fonctionnement interne: interruptions ?, vecteurs?, et les vecteurs
d'état des alarmes.
Les adresses 0x0200 à 0x06C6 contiennent les datas
actuelles: valeurs courantes des capteurs, min max et leurs dates etc.
le détail en est fourni plus bas.
Les adresses 0x06C6 à 0x13C0 contiennent les datas
sauvegardées pour le fichier history.
Au delà: 0x2000 à 0x23D0 puis 0x3000 à 0x33D0 etc
peut-être la ROM ?
Lecture de l'historique en mémoire
L'adresse 0x06B2 contient toutes les informations nécessaires
à
la lecture de l'historique en mémoire, sauf l'adresse de
début
de sauvegarde, qui est 0x06C6, et de fin qui est 0x13B0.
Adresse 0x06B2, 10 octets
Byte 0 : intervale de temps (minutes -1) entre deux écritures en
mémoire
d'une ligne de data
Byte 1 : [AB] A=Nb de minutes restant avant l'écriture de
la
prochaine ligne de sauvegarde; B non testé nibble poids fort ?
Byte 2 : Fonction inconnue semble tj 0
Byte 3 ->7 : Date et heure de la dernière écriture
sous
la forme [Min] [Heure] [jour] [mois] [année] chacun sur un octet.
Byte 8 : contient le rang de la dernière ligne
écrite.
(varie de 0 à 0xAF) 0xAF=175 = 175 enregistrements de 10
Octets. L'adresse écrite est donc égale à byte_8 *
0x13 + 0x06C6.
(0x13 = decimal 20), l'adressage se comptant en nibbles (donc
20).
Byte 9 : contient le rang de la ligne écrite la plus haute
en
mémoire. Ce pointeur varie de 0 à 0xAF. Il est remis
à
0 lors d'un reset de la station, ou lors d'un changement de l'intervale
de
sauvegarde (Byte 0). Il augmente jusqu'a 0xAF et garde cette valeur
tant
qu'il n'y a pas de reset ou de modification de l'intervale de
sauvegarde.
Donc connaissant la date et l'heure de la dernière sauvegarde,
et
le délai entre deux écritures, on peut calculer la date
et
l'heure de l'écriture de la ligne précédente. Sa
position
en est donnée par le pointeur du byte 8.
On peut remonter ainsi jusqu'à l'adresse 0x06C6.
Si le byte 9 est égal au byte 8 on s'arrètera là.
S'il
vaut 0xAF (175) on pourra redescendre de 0xAF jusqu'au rang juste au
dessus
du byte 8, à condition que l'on en ai le temps, d'où
l'interêt
du byte 1.
En pratique je calcule le nombre de rangs à lire depuis la date
de
ma dernière sauvegarde sur disque, l'adresse la plus ancienne,
et
je lis les lignes jusqu'a l'adresse la plus récente,
(pointée
par le byte 8).
Codage des données de l'historique en
mémoire
Ce décodage à été entièrement
mené
à bien par Kenneth Voir
aussi
le news group allemand
wetterfreaks
En plus
Attention à ma connaissance quand la station lit
des datas des capteurs aucun signal n'est transmit sur la rs232 donc
mettre
des états d'attente !
D'après ce que j'ai compris , lorsque le station reçoit
les data de ses capteurs, elle interrompt la transmission RS232. Sans
doute les
échanges capteurs sont ils , comme la RS232 l'affichage LCD, et
le
clavier station, gérés par IRQ. avec des priorités
différentes.
Cela explique pourquoi, si vous choisissez le mode date avec secondes
sur le LCD, et si vous utilisez la transmission filaire, et la RS232 en
même temps, il est si difficile d'utiliser la touche display.
Cela explique aussi pourquoi IL FAUT LIRE LE PLUS DE DATA POSSIBLE
D'UNE SEULE FOIS, quitte à réordonner les nibbles
ensuite..
Et donc aussi l'algorithme de mon prog : calcul dans un tableau des
valeurs à envoyer, et à recevoir dans un autre, avant de
démarrer la transmission, lecture d'un nombre important
d'octets, délais d'attente.
Les valeurs sont demandées par adresses et sont
lues par la rs232 en cacractères. Dans la station ce sont des
nibbles.
Configuration de test:
les adresses et formats ci dessous sont ceux d'une
station configurée avec:
Date d/m/y h:m:s
Pression hPa
Vitesse Vent km/h
Température °C
adresses: name_perl_pg, hexa address, nb char to read
# response description
[a,b] means 1 char or 2 Nibbles a and b
[a] means 1 byte or 1 char
#
"sec",0x0200,1 # [s]econds of actual date time
#
"date",0x0207,4 # [d] [m] [y] [12] ou 24 heures # here you
may vary if you are little or big endian
#
"Date_heures",0x023B,5 # [M]in [H]ours [DayLow,DayOfWeek]
[MonthLow,DayHigh] [Year,MonthHigh]
#
"heure_min",0x023B,2
#
"Vent",0x0527,3 # [Speed] (0.1 m/s) [Dir,Speed_high_nibble]
... more to come ...
#
"Dvitesse",0x04EC,15 # [?] [?] [?]
#
"Vent2",0x0512,3 # position alarme haute vent
#
"PluieT",0x0497,10
#
"Pluie24h",0x04B4,10
#
"Pluie1h",0x04D2,7
#
"TIn",0x0346,7
# date Tin Min Tin Max
"DTInMinMax",0x0354,10
# "TOut",0x0373,7
# date TOut Min TOut Max
"DTOutMinMax",0x0381,10
#
"HIn",0x03FB,3
#
"HOut",0x0419,3
# Date min max
"DHInMinMax",0x0401,10
# Date min max
"DHOutMinMax",0x041f,10
#
"WC",0x03A0,7
# Date min max
"DWCMinMax",0x03AE,10
#
"Dew",0x03CE,7
# Date min max "
DDewMinMax",0x03DC,10
#
"Evolution",0x026B,1
# pressions "PrCour",0x05D8,13
"PrMinMax",0x05F6,13
# Date min max "DPrMinMax",0x061E,10
"Alarm1",0x0019,4
#
"Alarm2",0x0020,4
# see above: HF Reception 0x0054C
"PtrSauve",0x054C,3 Compris par Kenneth
Voir aussi le news group allemand
wetterfreaks
Here is his post:
HF Reception
Address: 0x054C, length 3
Command: 82 96 92 B2 CE
Answer: 33 GH IJ KL cs
Decoding:
33 - Header/3 data bytes
G - 0=cable, 3=lost connection, F=Wireless connection (HF)
H - Unknown. Always value D.
J - Unknown. Always 0
LI - Countdown timer in binary mode.
Half seconds to next data collections.
Start value is 0F for cable, 3F for missing connection and FF for
wireless.
K - Unknown - value 0
cs - Checksum
My guess is that this is is used by the PC program to guess when the
unit receives data. There is a small red indicator marked "HF
Reception" in the PC program that indicates that the unit receives
data.
## delay between save 3 B, date late save (5 B), 2 Ptrs
Mem area last saved 2 B
"HeureSauve",0x06B2,10
More to come.
More info:
Un fichier détaillé au format .rtf a été
commencé
par Detlef
|