Datalogger et véritable tâche de fond

BESQUEUT

Senior Member
Pour mon premier post, je vais décrire mon projet en cours. Merci de faire part de vos commentaire.

L'idée, c'est de faire un datalogger qui pourra servir pour la domotique, en particulier alarme et station météo.
Le cahier des charges est le suivant :

- mesures aussi régulières que possibles, au moins une fois par seconde.
- agrégation et enregistrement sur clé USB toutes les 10 mesures environ,
- système enfoui dans le grenier ; donc nécessité de récupérer les données par une liaison série. (il reste la possibilité de récupérer la clé USB dans les cas graves, mais ce ne sera pas l'usage normal)
- possibilité de transmettre les données en temps réel.

Je suis parti sur la base d'un 40X2 et d'un Vdrive2 et les débuts sont satisfaisants.

Je n'ai pas trouvé de code satisfaisant pour dialoguer avec le vdrive en tâche de fond. Je m'explique :
- tous les exemples sont plus ou moins dérivés du même code,
- ils utilisent certes le scratchpad, mais pas de façon satisfaisante à mon avis !
- En effet, ces codes commencent systématiquement par une pause de plusieurs secondes "pour récupérer les données" On n'est plus en tâche de fond là...

La lecture d'un port série en tâche de fond a normalement pour but de laisser du temps au processeur pour faire son travail. Dans mon cas et pour fixer les idées, il mesure la vitesse du vent pour détecter les rafales. Si j'introduis des pauses de plusieurs secondes, je risque de manqer une rafale ; le système perd en pertinence.

Hors, en étudiant la doc, je constate que ces PICAXEs (que je découvre) sont très bien pouvus pour éviter ce problème. En effet, le scratchpad est un buffer CIRCULAIRE. Simplement les exemples de code donnés n'en tiennent pas compte et remettent systématiquement à zéro le pointeur, tuant dans l'oeuf les bénéfices d'un buffer circulaire.

Les premiers essais montrent que ce buffer marche très bien, et qu'il n'est nullement besoin de pauses pour lire le vdrive, renvoyer les données à la console et continuer à faire régulièrement des mesures, tout ça sans utiliser le multitâches.

Si d'autres sont intéressés, je peux donner une explication plus complète de l'utilisation d'un buffer circulaire.

Cordialement,
 
Last edited:

westaust55

Moderator
Bienvenue au forum de PICAXE.
Voter projet est très intéressant dans le concept.
Tenez svp d'autres ici au courant de votre progrès et signalez vos questions quand les difficultés surgissent.
 

BESQUEUT

Senior Member
Merci pour le message de bienvenue,
J'ai effectivement rencontré un problème avec la variable système ptr qui semble liée d'une façon obscure à

hserptr...
En effet, le code suivant fonctionne :

main:
w11=0 ' pointeur sur le scratchpad
Boucle:
' l'essentiel du programme est ici...

If hserinflag = 1 Then

ViderBuffer:
get w11,b4
sertxd (b4)
If w11 < 1024 Then ' incrémentation du pointeur sur le buffer circulaire
inc w11
Else
w11 = 0
End If
if w11<>hserptr then goto ViderBuffer
hserinflag=0
End If
Goto Boucle


... alors que le même programme en remplaçant la séquence d'incrémentation du pointeur par @ptrinc ne fonctionne

pas !
C'est dommage ; pourtant @ptrinc semble fait pour ça ?
Et le code suivant fonctionne :
#simspeed 0
main:
ptr = 1021
for b1 = 1 to 5
@ptrinc=b1
next b1

ptr = 1021
for b1 = 1 to 5
b2=@ptrinc
sertxd (#b1," ptr=" ,#ptr,"=>",#b2)
next b1

Le résultat transmis sur le terminal est le suivant :
'sertxd output - baud 9600,n,8,1
1 ptr=1022=>1
2 ptr=1023=>2
3 ptr=0=>3
4 ptr=1=>4
5 ptr=2=>5

Ma seule explication serait que les variales système ptr et hserptr sont plus ou moins liées dans le firmware du

PICAXE. Du coup, la modification de l'une (ptr) entraînerait la modification innoportune de l'autre (effet de

bord).

Si quelqu'un a déjà rencontré ce problème, je suis preneur de son avis.
De même, je suis preneur de tout code concernant l'utilisation du buffer circulaire pour le traitement de

données reçues sur le port série.

Cordialement,
 
Last edited:

westaust55

Moderator
Excuses si je n'ai pas correctement interprété ce que vous voyez comme problème. J'essayerai d'expliquer de l'information.

Vous commencez à stocker des données à l'endroit de zone de travail 1021. Le block-notes a 1024 endroits en tant que 0 à 1023.
Quand l'indicateur atteint l'extrémité du block-notes, il roule plus d'à l'endroit 0.


Là où vous avez les lignes de programme :
b2=@ptrinc
sertxd (#b1," ptr=" ,#ptr,"=>",#b2)

les données de l'indicateur d'endroit courant à par le @ptr d'indicateur sont placées dans b2 variable, puis la valeur de PTR est automatiquement incrémentée au prochain endroit.

Quand vous montrez alors les données et la valeur de l'indicateur (PTR), la valeur a été déjà incrémentée par 1 et a pu avoir roulé plus d'après 1023 à 0.

Vous obtenez l'informaiton que vous prévoyez avec ce code:


Code:
#simspeed 0
main:
  ptr = 1021
  for b1 = 1 to 5
    @ptrinc=b1
  next b1

  ptr = 1021
  for b1 = 1 to 5
    w3 = ptr
    b2=@ptrinc
    sertxd (#b1," ptr=" ,#w3,"=>",#b2)
  next b1
 

BESQUEUT

Senior Member
Circular buffer and @ptrinc

#simspeed 0
main:
ptr = 1021
for b1 = 1 to 5
@ptrinc=b1
next b1

ptr = 1021
for b1 = 1 to 5
b2=@ptrinc
sertxd (#b1," ptr=" ,#ptr,"=>",#b2)
next b1
Il n'y a pas de problème avec ce code.
C'était seulement pour valider le bon fonctionnement.
There is no problem with this code.
It was only to validate good working.


Mais par contre, le code suivant ne fonctionne pas (les données reçues sont erronées).
But following code is not working. (received data are erroneous)

main:
ptr=0
Boucle:
' l'essentiel du programme est ici... True main program...

If hserinflag = 1 Then
ViderBuffer:
get @ptrinc,b4
sertxd (b4)
if ptr<>hserptr then goto ViderBuffer
hserinflag=0
End If
Goto Boucle​
 
Last edited:

MGU

Senior Member
Bonjour,

Je ne sais pas si il a un rapport, mais il me semble que chaque picaxe a une plage de scratchad dédiée.

Ex: dans un programme sur 14M2, certaines variables indexées à partir de ptr=0 étaient systématiquement écrasées;
Aucun problèmes en commençant à ptr=30.

MM
 

BESQUEUT

Senior Member
Merci MGU pour la remarque. Selon la doc :
The scratchpad is a temporary memory area for storage of data such as arrays.
PICAXE-28X1, 40X1, 20X2 parts have 128 scratchpad bytes (0-127)
PICAXE-28X2, 40X2 parts have 1024 scratchpad bytes (0-1023)
Comme je suis sur un 40X2, j'ai bien 1024 emplacement mémoire dédiés au scratchpad.
En outre, en utilisant un pointeur 16bits "manuel" au lieu de @ptr, ça marche correctement.
C'est pour ça que je pense plus à un problème entre ptr et hserptr qu'à un problème du au scratchpad.

Par contre, il me semble que le 14M2 n'a pas de scratchpad. (ne pas confondre ptr et bptr...)
Cordialement,
JYB
 
Last edited:

westaust55

Moderator
GET n'est pas la bonne commande. Vous devez assigner le @PTRINC directement à la variable.

Essayez ce code :

Code:
main:
ptr=0 
Boucle:
' l'essentiel du programme est ici... True main program...

If hserinflag = 1 Then

ViderBuffer:
If hserinflag = 1 Then

[COLOR="#FF0000"][/COLOR][B]b4 = @ptrinc[/B]
sertxd (b4)
if ptr<>hserptr then goto ViderBuffer 

hserinflag=0
End If
Goto Boucle

Si vous devez seulement montrer l'information sans autre employez alors :

Code:
main:
ptr=0 
Boucle:
' l'essentiel du programme est ici... True main program...

If hserinflag = 1 Then

ViderBuffer:
If hserinflag = 1 Then

sertxd ([COLOR="#FF0000"][/COLOR][B]@ptrinc[/B])
if ptr<>hserptr then goto ViderBuffer 
hserinflag=0
End If
Goto Boucle
 
Last edited:

BESQUEUT

Senior Member
GET n'est pas la bonne commande. Vous devez assigner le @PTRINCE directement à la variable.
Very clever. Thank you westaust !
J'avais de la peau de saucisson devant les yeux ! I don't known how to translate that...

NB : il me semble que le deuxième "If hserinflag = 1 Then" est superflu.
NB : it seems to me that second "If hserinflag = 1 Then" is useless.
 
Last edited:

BESQUEUT

Senior Member
Disappointed

Je suis déçu par cette soit-disant réception série en tâche de fond.
En fait, il vaudrait mieux dire "réception série pendant la pause".
Le système de buffer circulaire semble marcher correctement. Le problème, c'est que suivant les instructions en cours d'éxécution (autre que "pause") la réception série ne marche pas !
C'est donc au final inutilisable, sauf erreur de ma part.

Si quelqu'un a réussi à faire marcher ce truc (en dehors d'une pause de plusieurs secondes) je reste preneur.

Cordialement,

JYB

I am disappointed with this so-called "background receive serial data".
Actually, I must say "pause receive serial data".
Circullar buffer is working well. But receiving data while Picaxe is doing other things than "pause" is not working !
To my mind, background receive is useless.

If anyone have make this working (without a few seconds pause) I stay OK to test it.

Thanks to all, specially WestAust55,
JYB
 

zebulon

Member
Bonjour Besqueut,

Si tu lis le manuel 1 à la section Parallel Task Processing, il est bien dit qu'il s'agit d'une simulation de multitâche (à l'image des processeurs Intel de l'époque d'avant les multi-cores).
C'est du pseudo multi-tâches ou du temps partagé.

Je suis d'accord avec toi, c'est inutilisable. D'autant plus que si une des tâches utilisent des instructions bloquantes, les autres tâches ne sont plus exécutées.

A+,
Guillaume

extrait du manuel 1 :
However the new PICAXE microcontroller educational range (M2 parts) can now
simulate &#8216;parallel processing&#8217;
by repeatedly switching between a number of tasks
at very high speed. This is made possible by the increased operating speeds of the
newer parts - for instance running 4 tasks at 16MHz is approximately equal to
running one task at 4MHz. All tasks therefore &#8216;appear&#8217; to be processed in parallel.
Parallel tasks are designed for educational use to simplify programming by
younger students. This is best demonstrated by example.
 

PieM

Senior Member
Bonjour,

Vous devriez regarder ces deux exemples de data logger: Ici et là :

Puisqu'il s'agit de mesures météo déportées à poste fixe, et non de mesures ambulatoires, il serait peut être plus judicieux d'utiliser une transmission HF des données en temps réel, ce qui laisse toute possibilité de les enregistrer en mémoire tampon, en eeprom, sur clé USB ou SD card, de les visualiser en direct.

Une petite remarque sur votre code :

Je ne vois pas l'instruction hsersetup et son mode background.

d'autre part, If hserinflag = 1 Then ? A quoi correspond hserinflag ?
Le flag de hserin est le flag6 : hserflag
Et comme c'est un flag d'interruption, le mieux est de l'utiliser en interruption avec setintflag .
 

BESQUEUT

Senior Member
Bonjour Besqueut,
Si tu lis le manuel 1 à la section Parallel Task Processing, il est bien dit qu'il s'agit d'une simulation de multitâche (à l'image des processeurs Intel de l'époque d'avant les multi-cores).
C'est du pseudo multi-tâches ou du temps partagé.
Je suis d'accord avec toi, c'est inutilisable. D'autant plus que si une des tâches utilisent des instructions bloquantes, les autres tâches ne sont plus exécutées.
En fait le 40X2 que j'utilise n'est pas multitache. Mais si la "lecture série en tâche de fond" fonctionne aussi bien que le multitache, je n'ai effectivement plus qu'à trouver une autre solution.
 

BESQUEUT

Senior Member
d'autre part, If hserinflag = 1 Then ? A quoi correspond hserinflag ?
Le flag de hserin est le flag6 : hserflag
Voir le manuel d'utilisation pour hsersetup:
Upon the hsersetup command the serial pointer
(hserptr) is reset to 0. When a byte is received it is saved to this scratchpad
address, the hserptr variable is incremented and the hserinflag flag is set (must be
cleared by user software)
Merci pour ces liens, même si je les avais déjà vus.
Le problème (et qui est le sujet du thread) c'est de savoir si la "réception série en tâche de fond" est ou pas utilisable.
L'objectif est par exemple de pouvoir transmettre le DIRrectory d'une clé USB, lequel comporte communément plus de 1024 caractères.
La solution théorique est d'utiliser un buffer circulaire et une réception série en tâche de fond (à condition que cette dernière fonctionne sans interraction avec le programme principal).
Je vais effectivement devoir adopter une autre approche ; c'est dommage parce que ces outils semblaient faits pour ça...
Dernière précisions : le code ci-dessus est effectivement incomplet, l'objectif étant de rechercher un problème sur le buffer circulaire et non sur la réception série.
Merci encore à WestAust55 qui a mis le doigt sur une erreur de syntaxe.
Je peux publier le code complet, mais c'est un peu stupide puisque ça ne marche pas.
Cordialement
 

PieM

Senior Member
Bonjour,

le manuel dit aussi :

The interrupt inputs condition is any pattern of ‘0’s and ‘1’s on the flags byte
masked by the byte ‘mask’. Therefore any bits masked by a ‘0’ in byte mask will be
ignored.
The system ‘flags’ byte is broken down into individual bit variables. See the
appropriate command for more specific details about each flag.
Name Special function Command
flag0 hint0flag X2 parts - interrupt on INT0 hintsetup
flag1 hint1flag X2 parts - interrupt on INT1 hintsetup
flag2 hint2flag X2 parts - interrupt on INT2 hintsetup
flag3 hintflag X2 parts - interrupt on any pin 0,1,2 hintsetup
flag4 compflag X2 parts - comparator flag compsetup
flag5 hserflag hserial background receive has occurred hsersetup
flag6 hi2cflag hi2c write has occurred (slave mode) hi2csetup
flag7 toflag timer overflow flag settimer


Quant au mode de fonctionnement réception série en tâche de fond, il fonctionne parfaitement avec le scratchpad et les communications en I2C, sachant que le picaxe n'est pas, dans ce cas, le maître de la communication.
l'objectif étant de rechercher un problème sur le buffer circulaire et non sur la réception série.
Mais vous dite dans autre un post que
Le système de buffer circulaire semble marcher correctement. Le problème, c'est que suivant les instructions en cours d'éxécution (autre que "pause") la réception série ne marche pas !
 

BESQUEUT

Senior Member
le manuel dit aussi :
flag5 hserflag hserial background receive has occurred hsersetup
Effectivement, ça semble assez incohérent. Ce qui est certain, c'est que hersinflag passe effectivement à 1 lors de la réception d'un caractère. Je n'ai pas essayé avec hserflag.

Quant au mode de fonctionnement réception série en tâche de fond, il fonctionne parfaitement avec le scratchpad et les communications en I2C, sachant que le picaxe n'est pas, dans ce cas, le maître de la communication.
Ce que je constate, c'est que la réception série en tâche de fond fonctionne si le PICAXE est en pause, mais pas si il fait autre chose.
En pratique, le fait d'ajouter des pauses plus ou moins longues améliore la réception, mais rends le programme inutilisable.
Si la réception série en tâche de fond fonctionnait, il ne serait pas nécessaire d'insérer des pauses dans le programme.

Si c'est possible, j'aimerais bien voir le programme de réception I2C en tâche de fond ; ça peut être instructif.

En tout cas merci pour votre réactivité,

JYB
 

PieM

Senior Member
Bonsoir,

En i2C il n'y a aucun problème, puisque par définition le bus est disponible pour tout maître qui veut écrire ou lire vers un esclave. J'ai par exemple un appareil avec des accéléromètres en esclaves, un 28X2 en esclave, et deux 18M2 en maîtres.
C'est le 28X2 qui est le coeur et il reçoit en toute transparence des informations des maîtres, et met à leur disposition des résultats de traitement, via son scratchpad.
Après initialisation de son adresse réseau, hormis des get et des put pour accéder à son scratchpad, aucune autre instruction n'est nécessaire.
De fait, la configuration en background de la liaison hser devrait permettre la même chose:
" Note that on X2 parts you may prefer to background receive the serial data into
the scratchpad (hence not requiring use of this command at all)"
Je n'ai malheureusement pas de Vdrive pour faire des tests.

Une solution que l'on adopte pour les cas difficiles comme la transmission HF, pourrait être de séparer les fonctions, et de traiter la liaison Vdrive avec un 08M2 dédié, en liaison I2C avec le 48X2 en mode slave.
 

BESQUEUT

Senior Member
" Note that on X2 parts you may prefer to background receive the serial data into
the scratchpad (hence not requiring use of this command at all)"
Je n'ai malheureusement pas de Vdrive pour faire des tests.
C'est peut-être possible de mettre en évidence le fonctionnement de la "réception série en tâche de fond" à partir d'une autre source de données série.
Par exemple un autre picaxe programmé pour envoyer de façon régulière une série de nombres, à disons 4800 ou 9600 bauds.
Le challenge serait de lire ces données et de les renvoyer sur la console à 38400 bauds (40X2 avec oscillateur à 8 Mhz)
Le code pour lire le buffer circulaire existe.
Sinon, pour le VDrive, je vais m'intéreser aux broches prévues pour le contrôle de flux que j'avais laissé de coté dans un premier temps puisqu'il semblait possible de lire les données à la volée. Dans ce cas, il devrait être possible de demander au VDrive d'arrêter d'envoyer des données quand le PICAXE est occupé. Ce sera moins performant, mais ça devrait marcher.
Cordialement,
JYB
 
Top