Webteo : Explication du programme PicBasic

Transcription

Webteo : Explication du programme PicBasic
Explication du programme
du PicBasic
Projet Webteo 2009/2010
'*****************************************************************
'
DECLARATION DES CONSTANTES
'*****************************************************************
const BYTE k_array=(0,'A','I','O','T','C') 'Liste des variables
Const CL_MSB_Adr = &H0FFE
Const CL_LSB_Adr = &H0FFF
Const BDS = 50
'Vitesse de transmission (103=9600bds/50=19200bds)
Const RXD = 8
Const TXD = 9
Const
Const
Const
Const
SDA
SCL
CTRL_R
CTRL_W
Const
Const
Const
Const
O0
O1
O2
O3
=
=
=
=
'Avant dernier emplacement mémoire
'Dernier emplacement mémoire
'Broche utilisée pour réception série=I/O8
'Broche utilisée pour émission série=I/O9
=
=
=
=
10
11
&b10100001
&b10100000
12
13
14
15
'Broche donnée I2C=I/O10
'Broche horloge I2C=I/O11
'Octet de contrôle lecture
'Octet de controle ecriture
'Sortie
'Sortie
'Sortie
'Sortie
O0=I/O12
O1=I/O13
O2=I/O14
O3=I/O15
'*****************************************************************
'
DECLARATION DES VARIABLES
'*****************************************************************
DIM Adr
AS INTEGER
'Pointeur Adressage eeprom
DIM V
AS INTEGER
'Valeur analogique
DIM u
AS INTEGER
'Unité valeur analogique
DIM d
AS INTEGER
'Dizaine valeur analogique
DIM c
AS INTEGER
'Dixième valeur analogique
DIM CL
AS INTEGER
'Content-Length
DIM i
AS BYTE
'Divers
DIM j
AS BYTE
'Divers
DIM k
AS BYTE
'Divers
DIM l
AS BYTE
'Divers
DIM pos_T AS BYTE
'Position du texte LCD
DIM Cpt
AS INTEGER
'Compteur de connexion
DIM GETHTTP(50) AS BYTE
'Requête HTTP
Cette première partie de code déclare les constantes puis les variables. Les
constantes étant déclarées par « CONST » et les variables par « DIM ».
La toute première constante est un tableau contenant une liste de variables.
Les variables et constantes peuvent prendre divers types de valeurs. Cela joue sur la
capacité de mémoire alloué à la variable et donc, les valeurs extrêmes qu'elle peut
prendre.
Voici un tableau récapitulant les différents types de données possibles :
Type de donnée
Taille
Valeurs possibles
(Minimum .. Maximum)
byte
8-bit
0 .. 255
char
8-bit
0 .. 255
word
16-bit
0 .. 65535
short
8-bit
-128 .. 127
integer
16-bit
-32768 .. 32767
longint
32-bit
-2147483648 .. 2147483647
Noter aussi la présence des commentaires par l'apostrophe qui les précède. Ces
commentaires améliorent la compréhension du programme ; la lecture du code tel quel
n'étant pas une chose aisée, pour un développeur reprenant le programme, par
exemple.
'
INITIALISATIONS
'===========================================================================
Cpt=0
'Initialisation du compteur de connexions
INIT:
'
Initialisation des sorties
'-----------------------------------------------OUT O0,0
OUT O1,0
OUT O2,1
OUT O3,0
'
Initialisation de l'afficheur LCD
'----------------------------------------SET PICBUS HIGH
LCDINIT
CLS
LOCATE 0,0 : PRINT "Station meteo"
LOCATE 5,1 : PRINT "WEBTEO"
'
Calcul du Content-Length
-------------------------------------------------CL=EEREAD(CL_MSB_Adr)
CL=CL*256
i=EEREAD(CL_LSB_Adr)
CL=CL+i
'RAZ
'RAZ
'RAZ
'RAZ
O0
O1
O2
O3
'PICBUS à 19200bds
'Initialisation LCD
'Efface LCD
'Message d'accueil Ligne 1
'Message d'accueil Ligne 2
'Lecture MSB CL
'Calcul CL
'lecture LSB CL
'Calcul CL
Cette nouvelle partie de programme à pour but d'initialiser le comportement du
PicBasic.
Tout d'abord, le compteur de connexions ( visible sur la page HTML du Picbasic ) est
mis à zéro.
Ensuite, on place un marqueur « INIT: » qui définit la ligne à partir de laquelle il
faudrait reprendre l'initialisation ( instruction « GOTO INIT » ).
Puis, les 4 sorties sont mises à zéro ( état bas ).
L'écran est à sont tour initialisé. On l'efface puis on écrit le message d'accueil :
Station meteo
WEBTEO
Enfin, on utilisant l'instruction « EEREAD(ADR) ». Cette instruction permet de
récupérer une donnée à l'adresse (Adr) dans la mémoire FLASH du"PICBASIC".
Ici, on lit le Bit de poids fort contenu à l'avant dernier emplacement mémoire
( &H0FFE ) , puis le Bit de poids faible au dernier emplacement mémoire ( &H0FF ).
Ceci afin de calculer le Content-Length ( L'en-tête Content-Length permet au serveur
d'indiquer au client la taille exacte du corps du message, ce qui permet au client de
déterminer exactement quand celui-ci a été entièrement transmis ).
'
MISE A JOUR DES SORTIES DE LA CARTE ET DE L'ECRAN LCD
'==========================================================================
DEBUT:
'Attente connexion client http
'-------------------------------------------SERIN RXD,BDS,0,1000,DEBUT,[UNTIL(13),GETHTTP(0)~49]
'Enregistrement des caractères reçus dans la variable GETHTTP
'tant que caractère <> retour chariot (=13)
'Redirection vers sous programme de programmation eeprom
'------------------------------------------------------------IF GETHTTP(0)="P" THEN
'Si 3 premiers caractères = "PRG"
IF GETHTTP(1)="R" AND GETHTTP(2)="G" THEN GOTO PRG
'enregistre les caractères suivants dans l'eeprom (page HTML)
END IF
'
'Incrémentation du compteur de connexions
'-------------------------------------------Cpt=Cpt+1
SEROUT TXD,BDS,0,0,["HTTP/1.0 200 OK",13,10]
'Accusé de réception requête accomplie correctement
'Lecture des données contenues dans l'adresse html
'---------------------------------------------------j=0
'
FOR i=0 TO 49
'Lecture variable tableau GETHTTP
IF GETHTTP(i)="?" THEN j=i+3
'Si "?" détecté => mémorisation dans j position début texte
NEXT i
IF j>0 THEN
'Si j>0
'Mise à jour des sorties
------------------------------------------------IF GETHTTP(j)="1" THEN OUT O0,1 ELSE OUT O0,0
j=j+1
IF GETHTTP(j)="1" THEN OUT O1,1 ELSE OUT O1,0
j=j+1
IF GETHTTP(j)="1" THEN OUT O2,1 ELSE OUT O2,0
j=j+1
IF GETHTTP(j)="1" THEN OUT O3,1 ELSE OUT O3,0
'Affichage du texte sur l'écran LCD
'-------------------------------------j=j+4
pos_T=j
k=j+32
LOCATE 0,0
l=j+16
CLS
FOR i=j TO k
IF GETHTTP(i)="+" THEN GETHTTP(i)=32
IF i=l THEN LOCATE 0,1
PRINT GETHTTP(i)
NEXT i
END IF
'mise à
'
'mise à
'
'mise à
'
'mise à
jour sortie O0
jour sortie O1
jour sortie O2
jour sortie O3
'Position début texte
'Mémorisation position
'Position fin du texte
'Position curseur
'
'
'
'Remplace le + par un espace
'Passage 2ème ligne afficheur
'Affichage caractère sur LCD
'
On retrouve tout d'abord le marqueur « DEBUT » fonctionnant à l'identique du
marqueur « INIT » que j'ai expliqué précédemment.
Ensuite, on récupère les caractères reçus dans la variable GETHTTP, c'est à dire les
données qui suivent l'adresse web. La chaine de caractères de l'adresse est lue du
premier caractère (0) au cinquantième (49), mais si le caractère lu est un retour
chariot, la chaine est considérée comme terminée, donc la lecture s'arrête.
Ensuite viens la séquence servant au stockage de la page HTML dans l'EEPROM. Si les
3 première lettres de la variable GETHTTP sont « PRG » alors la séquence de
stoskage peut être exécutée, et le programme va directement au marqueur « PRG »
situé plus loin (j'y reviendrait par la suite ).
Si ces caractères diffèrent de « PRG » la séquence n'aura pas lieu.
Puis le compteur de connexion est incrémenté de 1, et le PicBasic renvoie un accusé de
réception informant le client que la requête s'est accomplie correctement.
Enfin, la dernière partie de ce morceau de code est longue mais simple. Le Picbasic lit
une nouvelle fois la requête GETHTTP et en ressort l'état des 4 sorties et le texte à
afficher sur l'écran LCD, demandés par le client.
'
ENVOI DE LA PAGE HTML AU CLIENT HTTP
'================================================================
'Envoi de l'entête http
'--------------------------------------------------SEROUT TXD,BDS,0,0,["Content-Type: text/html",13,10]
'Type de contenu : html=text/html (si wap=text/vnd.wap.wml)
SEROUT TXD,BDS,0,0,["Content-Length: ",DEC(CL),13,10]
'Longueur du corps de la réponse
SEROUT TXD,BDS,0,0,[13,10]
'Ligne vierge
'Envoi du code html
'--------------------------------------------------GOSUB I2C_START
'Condition de START
SHIFTOUT SCL,SDA,2,CTRL_W,8
'Octet de controle ECRITURE
SHIFTOUT SCL,SDA,2,0,8
'Adresse du 1er octet à lire (MSByte)
SHIFTOUT SCL,SDA,2,0,8
'Adresse du 1er octet à lire (LSByte)
GOSUB I2C_START
'Condition de START
SHIFTOUT SCL,SDA,2,CTRL_R,8
'Octet de controle LECTURE
Cette partie du programme crée et envoie la page HTML au client. Tout d'abord, il y a
l'en tête de la page qui signale au navigateur du client qu'il s'agit s'une page HTML et
qui lui définit la longueur du Content-Length. Puis saute une ligne.
Ensuite le Picbasic démarre la lecture de la page HTML dans l'EEPROM ( je reviendrai
plus en détail sur ceci par la suite ).
SUITE_RAZ:
i=0:j=0:k=0
'initialisation des variables
SUITE:
j=SHIFTIN(SCL,SDA,1,8)
IF j=26 THEN GOTO I2C_NOACK ELSE GOSUB I2C_ACK
'Lecture de la donnée
'Envoi acknowledge
ON k GOTO 100,1,2,3,4,5
'branche sur une
'ligne en fonction de la valeur de k (ex: si k=1 branche sur la ligne 1)
Ici, les variables i, j et k sont mises à 0 puis le PicBasic lit un octet dans l'EEPROM.
Puis envoie un bit d'« acknoledge » à l'EEPROM signifiant que la lecture s'est
correctement accomplie.
La dernière instruction envoie à un certain marqueur en fonction de la valeur de k : si
k=0 envoi au marqueur 100, si k=1 envoi au marqueur 1, …
'LECTURE ANALOGIQUE
'-------------------------------------------------------1
j=j-48
V=ADIN(j)
'Lecture donnée analogique
GOSUB CONV
'SP conversion mesure
SEROUT TXD,BDS,0,0,[u,",",d,c]
'Envoi valeur mesurée u,dc
GOTO SUITE_RAZ
'Branche sur l'étiquette SUITE_RAZ
Il s'agit ici de la séquence associée au marqueur 1.
La lecture de la broche j (variable) est lue puis convertie d'une tension en ASCII. Puis
envoyée au navigateur du client.
Puis retourne au marqueur « SUITE_RAZ ».
'LECTURE NUMERIQUE DES ENTREES
'--------------------------------------------2
j=j-48
'ASCII -> DECIMAL
j=j+17
'n° entrée concernée
j=IN(j)
'Lecture état entrée
j=j+48
'DECIMAL -> ASCII
SEROUT TXD,BDS,0,0,[j]
'Envoi état entrée
GOTO SUITE_RAZ
'Branche sur l'étiquette SUITE_RAZ
Cette séquence associée au marqueur 2, lit l'état de l'entrée numérique j , puis la
convertie de tension en ASCII et l'envoie au navigateur du client.
Enfin le programme retourne au marqueur « SUITE_RAZ ».
'LECTURE NUMERIQUE DES SORTIES
'--------------------------------------------3
j=j-48
'ASCII -> DECIMAL
j=j+12
'n° sortie concernée
j=OUTSTAT(j)
'Lecture état sortie
j=j+48
'DECIMAL -> ASCII
SEROUT TXD,BDS,0,0,[j]
'Envoi état sortie
GOTO SUITE_RAZ
'Branche sur l'étiquette SUITE_RAZ
Cette séquence associée au marqueur 3, lit l'état de la sortie numérique j , puis la
convertie de tension en ASCII et l'envoie au navigateur du client.
Enfin le programme retourne au marqueur « SUITE_RAZ ».
'ECRAN LCD
'----------------------------------------------------------------4
IF pos_T>0 THEN
'Si texte modifié depuis RAZ serveur
l=pos_T+32
'Borne sup (32 caractères)
FOR j=pos_T TO l
'
SEROUT TXD,BDS,0,0,[GETHTTP(j)]
'Envoi des 32 caractères
NEXT j
'
ELSE
'
SEROUT TXD,BDS,0,0,["WEBTEO
"] 'Texte par défaut
END IF
'
GOTO SUITE_RAZ
'Branche sur l'étiquette SUITE_RAZ
Ici, la séquence associée au marqueur 4 écrit sur l'écran LCD le nouveau message
( envoyé par le client ), s'il y en a un, ou écrit sur l'écran LCD :
WEBTEO
Puis le programme retourne à « SUITE_RAZ ».
'COMPTEUR DE CONNEXIONS
'---------------------------------------------------5
IF j="P" THEN SEROUT TXD,BDS,0,0,[DEC(Cpt)]
'Envoi donnée compteur
GOTO SUITE_RAZ
'Branche sur l'étiquette SUITE_RAZ
Cette séquence dont le marqueur est 5, envoie au navigateur du client la variable
contenant le nombre de connexions effectues sur le PicBasic depuis la dernière
remise à zéro.
Enfin le programme retourne à « SUITE_RAZ ».
100
IF i="$" THEN
FOR k=1 TO 5
IF k_array(k)=j THEN GOTO SUITE
NEXT k
END IF
'
'si caractère n-1 = $
'
'
'
'
IF j<>"$" THEN SEROUT TXD,BDS,0,0,[j]
'Envoi resultat sur port série
i=j
'Caractère n-1 = caractère n
GOTO SUITE
'Branche sur étiquette SUITE => Lecture donnée suivante
Cette séquence associée au marqueur 100, si i a la valeur du caractère $, le
programme attribue une valeur à k et défini le type de variable à envoyer ( utilisation
du tableau « k_array » :
$A0,$A1,$A2,$A3
$I0,$I1,$I2,$I3
$O0,$O0,$O0,$O0
$T0
$CP
->
->
->
->
->
entrées analogiques
entrées logiques
sorties logiques
texte sur écran LCD
compteur de connexions depuis dernier RESET
).
Sinon, le programme envoie la valeur de j et retourne à « SUITE ».
Voici à présent les sous-programmes :
Les sous-programmes sont appelées par « GOSUB » et retournent au programme
appelant à la fin de leur execution « RETURN ».
Pour comprendre pleinement ces sous programmes, il est recommandé de se reporter
aux documents sur le protocole I²C.
'I2C : ECRITURE 1 octet
'============================================================================
I2C_WRITE_BYTE:
GOSUB I2C_START
'Condition de START
SHIFTOUT SCL,SDA,2,CTRL_W,8
'Octet de contrôle LECTURE
i=Adr/256
'Octet de poids fort
SHIFTOUT SCL,SDA,2,i,8
'Adresse début écriture (MSByte)
i=Adr
'Octet de poids faible
SHIFTOUT SCL,SDA,2,i,8
'Adresse début écriture (LSByte)
SHIFTOUT SCL,SDA,2,j,8
'Ecriture en eeprom de j
Adr=Adr+1
'Incrementation pointeur adresse
DELAY 5
'Tempo 5ms
GOSUB I2C_STOP
'Condition de STOP
DELAY 5
'Tempo 5ms
RETURN
Ce sous-programme, exécute la procédure d'écriture d'un octet dans l'EEPROM.
Il démarre la discussion en prenant le contrôle de la ligne puis signale sa volonté
d'écrire des données dans l'EEPROM. Puis il écrit l'octet à écrire puis arrète la
transmission en libérant le contrôle de la ligne (au cas où il y aurait plusieurs maitres
voulant prendre le contrôme de la ligne).
'I2C : START
'============================================================================
I2C_START:
OUT SCL,0
'SCL=0
OUT SDA,1
'SDA=1
OUT SCL,1
'SCL=1
OUT SDA,0
'SDA=0
OUT SCL,0
'SCL=0
RETURN
'I2C : STOP
'============================================================================
I2C_STOP:
OUT SCL,0
'SCL=0
OUT SDA,0
'SDA=0
OUT SCL,1
'SCL=1
OUT SDA,1
'SDA=1
OUT SCL,0
'SCL=0
RETURN
'I2C : ACKNOWLEDGE (émis par le PicBasic)
'============================================================================
I2C_ACK:
OUT SCL,0
'SCL=0
OUT SDA,0
'SDA=0
OUT SCL,1
'SCL=1
OUT SCL,0
'SCL=0
RETURN
'I2C : NO ACKNOWLEDGE (émis par le PicBasic)
'============================================================================
I2C_NOACK:
OUT SCL,0
'SCL=0
OUT SCL,1
'SCL=1
OUT SCL,0
'SCL=0
GOSUB I2C_STOP
'Condition de STOP
GOTO DEBUT
'Retour au début du programme
Ces sous-programmes correspondent aux séquences I²C de début de transmission
(I2C_START), de fin de transmission (I2C_STOP), d'acquittement (I2C_ACK), et de
non-acquittement (I2C_NOACK) dans quel cas le comportement à adopter est l'arret
de la transmission.
'Conversion DECIMAL -> TENSION -> ASCII : x,xx
'============================================================================
CONV:
V=V/4
'Résolution 10 bits -> 8 bits
V=(100*V)/51
'Calcul tension nombre entier
u=V/100
'Calcul unité
c=100*u
d=(V-c)/10
'Calcul dixième
c=c+(10*d)
c=V-c
'Calcul centième
u=u+48
'Unité
-> CODE ASCII
d=d+48
'Dixième -> CODE ASCII
c=c+48
'Centième -> CODE ASCII
RETURN
Dans ce sous-programme, la valeur (en Volts) de l'entrée analogique (mais en
numérique pour le moment) est convertie de 10 bits à 8 bits en divisant la valeur par
2² soit 4.
Le nombre de volts (en 8 bits ) est alors convertie en une valeur analogique en
multipliant la valeur numérique par le quantum qui est de 1/51 .
Plus précisément:
q = 5V/(2^8) = 5/256 = 1/51,2 = 19,5mV
Mais ici la valeur du quantum appliquée est 1/51 afin de simplifier les résultats.
Ensuite la valeur analogique est alors répartie dans 3 variables : une contient les
unités (u), un autre les dixièmes (d) et une dernière les centièmes (c). Il n'y a pas de
dizaines car l'entrée analogique ne peut dépasser 5V.
Enfin on ajoute 48 à u, c et d pour les transformer en valeurs ASCII. En effet :
Caractère
Valeur décimale ASCII
0
0 + 48 = 48
1
1 + 48 = 49
2
2 + 48 = 50
3
3 + 48 = 51
4
4 + 48 = 52
5
5 + 48 = 53
6
6 + 48 = 54
7
7 + 48 = 55
8
8 + 48 = 56
9
9 + 48 = 57

Documents pareils