RCCL V4 : développement du software
version
provisoire d'une documentation technique
Cette évolution de la version V2 a un objectif:permettre l'édition du
fichier source avec l'émetteur seul, sans la nécessité d'un PC.
Elle conserve le langage RCCL inchangé (un émetteur V2 et un émetteur RCCL++
utilisent le même fichier "source")
Elle utilise un micro 32 bits et plus de mémoire, pour optimiser la clarté
du programme plutôt que l'encombrement mémoire.
En utilisant C++ on se facilite la programmation (approche objet, strings,
gestion de listes ...) et l'utilsation est beaucoup plus confortable grâce à
l'écran touchscreen.
Pour réaliser ceci, le choix hardware est
- un micro 32 bits avec une mémoire de 32k à 64k (au lieu des 4k de la
version V2)
Le développement se fait avec un MBED
(ARM Cortex M3 32k) . Ceci est particulièrement confortable: il ne faut
installer aucun programme, compilateur...tout se passe avec le web et
surtout, il dispose d'une très bonne library (closed source)
Cependant je souhaite garder la possibilité d'utiliser un outil de
développement open-source , avec le mbed ou un autre processeur,
par exemple un STM32
- un display graphique touchscreen
La firme 4D propose des combinaisons impressionnantes d'écran graphique
couleur, carte SD, extensions digitales...le tout accessible au travers
d'un interface série .Le choix est un µLCD-24PT
(SGC)
- le nombre d'entrées-sorties digitales est suffisant ,aucune extension
n'est nécessaire (grâce au lcd 4D)
Une autre solution serait d'utilser des extensions I2C ou SPI MCP23S08
ou MCP23S17
Pour les entrées analogiques il faudra compléter le MBED avec un MCP3208
(accès SPI, 8 canaux 12 bits).
Il y a deux raisons: d'une part pour augmenter le nombre des entrées,
d'autre part le MBED a des entrées analogiques de mauvaise qualité, trop
"bruyantes".
- alimentation simple, optimisée pour un usage 2.4G, lipo 2S et
interrupteur électronique.
- module FM séparé, comportant sa propre batterie 9.6V ou un
élévateur de tension.(je ne vole presque plus en 35 et ceci sera un
module attachable en cas de besoin au dos de l'émetteur)
Compilation:
Le MBED est directement prêt à l'emploi. Les compilations par "cloud" sont
plus lentes que les compilations locales, car il compile toujours tout le
projet, mais suffisamment rapides. Le "programmeur" USB qui est très rapide.
Les drivers sont très faciles à utiliser.
La programmation se fait en C++, en utilisant les classes "vector" et
"string", ce qui représente un réel confort comparé à C.
Fin novembre 2011, Mbed propose une compilation
off-line, avec par exemple un compilateur GCC (Codesourcery lite).
La library mbed reste cependant closed-source.
Cette procédure fonctionne bien et me permet d'utiliser un éditeur de
meilleure qualité (Scite) et de disposer d'un "folding" du code.
Organisation générale:
- folder hwxxx: ce qui dépend du microprocesseur xxx (mbed ou autre).
- hwjeti devrait rassembler tout ce qui concerne Jeti...pour ceux qui
utilisent d'autres modules
- folder core : toute l'application ,qui est indépendante du
microprocesseur (mais dépend du display)
comporte en particulier core.h et calc.h, les deux headers
- programme principal rccl.cpp
Mémoire RAM
Le micro LPC 1768 dispose de 64k mais attribue 32k aux périphériques tels
que Ethernet, Usb externe...il ne resterait donc que 32k pour le programm
C++.
On peut cependant définir certaines tables au delà de cette limite de 32k ,
c'est le cas pour la table des opérations.
struct rccl_data rc
Cette structure comporte les données communes à tous les programmes
struct rccl_data {
string current_file; //current model file name ,without
the extension
Calc* calcptr; // pointer to the current calc
object (NULL if not loaded)
Lcd4D*lcdptr; // pointer to the lcd object
set<short> *varSelection; //selection of index to
the variables to display in some menus (normal empty)
int rccl_task_tick; //ticker at the beginning of
the last rcloop
};
Lcd.cpp : gestion du display et du touchscreen
voir core.h
Lcd4D: constructeur d'un "objet" pour gérer le display. (uniquement pour le
confort, car il n'y a évidemment qu'une seule instance)
L'initialisation est lente (délai de plusieurs secondes; initialise le
display, change la vitesse de communication, charge les calibrations du
touchscreen ).
Les fonctions sont programmées selon les besoins de RCCL: ceci n'est pas un
"driver" à usage universel.
- Cmd envoie une commande et vérifie la réponse ack/nak,
- CmdS envoie une partie de la commande,
- PutString envoie un string
- Ack vérifie la réponse (stop si erreur !!) sans
bloquer le fonctionnement en temps réel.
(voir la fonction getc() dans lcdhw, qui appelle rccl_task)
- Cls clear screen
- Control voir les commandes de contrôle
- Color converti une couleur RGB en 2 bytes pour 4D
- Textg écrit un texte en mode graphique (coordonées pixel , taille
variable)
- TextCmd est une variante simplifiée (font, taille couleur sont fixes),
utilisé pour la ligne de commande
- ArrowCmd écrit des "flèches"
- Text écrit un texte en mode texte (coordonées ligne/colonne)
- Int transforme les coordonnées x,y (pixel) en 4 command bytes
- Pen
- Rectangle command \x72
- Point affiche un simple "point" (utilisé pour calibrer)
- GetTouchBrut = acquisition des cordonnées du touchscreen non calibrées
(fonction non bloquante - appelle rccl_task())
- GetTouch renvoie les coordonées calibrées .(bloquant: la fonction
attend une réponse de l'écran)
- GetTouchNB est identique à GetTouch mais non bloquant. Return true si
de nouvelles coordonées ont été lues et sont disponibles, return false
si aucun nouveau "touch"
Le mode de touch est variable:
- normalement touch si "press"
- variante touch si "moving", utilisé pour un slider
- La fonction Calibrate est utilisée une seule fois, au setup, elle
affiche des points, demande de les "toucher" et calcule les coéfficients
de calibration
- composants graphiques pour simplifier l'écriture des menus
Grt affiche un texte, mais ne repeint l'écran que si le texte change ,
ce qui évite un clignotement dabs les données remises à jour en
permanence
- PinGet(n) fournit la dernière valeur de l'entrée digitale n
- les fonctions liées aux sons sont play (pour jouer un fichier son) et
getSoundLen pour connaître la durée d'un fichier son.(voir sound.cpp)
Les fonctions dépendant du microprocesseur sont dans hw/lcdhw.cpp
- getc et putc isolent l'appel de l'UART et ne bloquent pas les
programmes en temps réel, en passant le controle à rccl_task
getcB est par contre bloquant, pour ne pas interrompre une
transmission de plusieurs caractères du Lcd-> mbed (> 8
bytes du buffer )
- Fast change la vitesse de transmission (115200 avec le bread board)
- CalibrateWrite écrit le fichier de calibration, CalibrateREAD le lit
- PinRead lit les entrées digitales et les enregistre dans la table Pin
et un registre préservé lors d'un redémarrage
(ceci parce que la lecture digitale n'est possible que si le lcd est
libre)
- PinRestor transfère ce registre dans la table au moment d'un
redémarrage)
Fonctions de gestion de fichier
Trois possibilités: le file system local propre au Mbed, le file system de
4D et le standard FatFs avec une carte SD externe.
Le programme filey.cpp
utilise le filesystem local du mbed. Il démarre rapidement, il est facile à
partager avec le PC (le mbed se comporte comme un stick USB )...mais il
masque les interruptions. On ne peut donc pas l'utiliser en cours de vol.
C'est le système utilisé.
Il est possible d'écrire un programme similaire utilisant une carte SD
séparée et le software FatFS, qui
n'aurait aucun de ces inconvénients.
File system du
Lcd:
Le filesystem de 4D ne peut pas démarrer rapidement.
Certaines communications comportent un message long envoyé par le Lcd et
ceci ne peut pas être interrompu.
Ce système est utilisé pour les sons et la synthèse vocale.
La carte doit être formatée en mode FAT16(Linux: utiliser Gparted ; Windows
...devrait le faire):
Les noms de fichier dans le vieux format DOS 8.3 majuscules , chiffres,
quelques signes spéciaux http://en.wikipedia.org/wiki/8.3_filename
Mdx.cpp : gestion d'un fichier "modèle"
voir core.h
Le but est de charger un fichier . mdx en mémoire, puis d'extraire les
lignes et les "tokens"
- Mdx(f) construit un objet mdx à partir du fichier f
- save écrit le fichier en conservant le même nom
- getline(i) acquiert le ligne i en vérifiant les bornes (returns un
string)
- gettokens transforme la ligne i en tokens (returns un vector de
strings)
- Tokenize est une fonction de service pour transformer un string en
tokens
- getnblignes
- replace remplace dans un string toutes les occurences d'un substring
- debugprint() imprime tout le fichier
- tokenprintf imprime un vector de tokens
- manque save (x) pour sauver sous un autre
nom
Les fonctions dépendant du hardware sont dans hw/filex.cpp:
l'échange de données entre le filesystem local du mbed et un fichier en
mémoire représenté par un objet Mdx.
Ed.cpp
voir core.h
Editeur d'un fichier ...ce qui était la raison de passer de V2 à V4 !
- constructeur Ed(string f) utilise le nom du fichier et
crée un objet Mdx (=le fichier en mémoire) puis le présente à
l'édition.
- setfont calcule le nombe de lignes/colonnes disponibles elon le font
- display affiche le fichier et permet de sélectionner une ligne
Si aucune ligne n'est
sélectionée, la ligne inférieure (ligne de commande) affiches les
symboles de pagination pour se déplacer dans le fichier
Si une ligne est sélectionnée, la ligne de commande affiche les options
de traitement
- displayLine pour éditer une ligne
- displayHelp
pour une ligne CALL d'un autre module...affiche ce modulke
pour toute autre ligne, affiche un fichier help pour le code opération
(à réaliser, help sur la carte sd )
- displayline est l'éditeur d'une ligne
hw/timer.cpp
Génération d'un signal ppm
gestion d'un pseudo systick
GetTicker() returns un nombre incrémenté de
1 toutes les 10msec
Remarque: la librarie du mbed utilise un seul timer(timer3).
Calcload.cpp
voir calc.h
Ceci charge un modèle en mémoire.
Il construit un objet Calc(f) (Le constructeur appelle expandfile(f) pour
lire les modules et crée toutes les variables en mémoire)
Structures
significatives:voir calc.h
- un vector de variables. Chaque variable est accédée rapidement par son
index dans la table.
L'accès par le nom est possible.
- un vector de libellés (variables string, pour les messages d'alarme)
- la classe opération n'est utilisée que pendant le chargement du
modèle. Elle n'est pas utilisée pour stocker les opérations, car la
double structure de "vectors" était trop gourmande en mémoire.
- une grande table de variables 16 bits (short) réservée aux opérations
, inscrites en séquence comme en version V2.
(option dans core.h: réserver en dehors des premiers 32k)
Chaque opération comporte
- un code opération (1 char) + nombre de variables , combinés en un
short (16 bits)
- les numéros de lignes du fichier et du module, combinées également
en un short (pour les messages d'erreur)
- un suite de variables exprimées en short (16bits). Le premier
argument est la variable de sortie, si elle existe pour ce code
opération.
Chaque argument représente soit une valeur constante, soit l'index
d'une variable (argument= entier en 16 bits (short) ):
- entre -12500 et +12500: c'est une valeur constante (représentation
interne voir TOINT)
- si >+20000, on soustrait 20000 pour déterminer l'index de la
variable (TOVAR=20000)
Chaque code opération
connait la nature (numérique, logique, string) de ses arguments et la
présence d'une variable de sortie. Seul le nombre total peut varier.
Fonctions :
- valcheck (x) restreint une variable numrique
- Var(..) constructeur pour une variable
- expandfile (f) lit le fichier f et effectue l'expansion des modules
(CALL CALLP) apellés par f. Pour chaque ligne il appelle insert pour
charger les données
- erreur gère les messages d'erreur
(pour le moment un simple printf...à modiifer)
- get_code_operation renvoie une structure code_operation qui définit
les caractéristiques du code
- addVar ajoute une variable, si elle n'existe pas encore, ou vérifie la
compatibilité avec la varible préexistante
- getVarIndex recherche l'index d'une variable en fonction du nom
- insert charge les données en mémoire RAM: le vecteur de varaibles et
la table des opérations....achevé au 26/3/2011
- param_restore lit le fichier de paramètres et le charge en mémoire
Formats déterminés par le premier token
2 nn vvvv name format de la version 2
vvvv=valeur name=nom du paramètre vvar (nn est l'index pour le programme
V2,initilisé ici)
4 vvvv name ce
format sera lisible par le simulateur V2
4D n
name affecter le
paramètre pvar name au trim n
- param_save sauve fichier de paramètres
- gérer un objet "opérations" qui encapsule tout le vecteur
d'opérations,stocké de façon non standard.
- setinit pour initialiser
- setoperation pour ajouter une opération en séquence
- getinit pour se placer au début
- getnext pour se positionner sur l'opération suivante et charge les
paramètres du code opération
- get...de chaque information pour une opération
- numéros de ligne
- nombre de variables invar (ce qui permet de gérer les paramètres
optionnels
- variable invar index i
- variable outvar (si prévue par le code opération (get puis set)
- convert essaie de convertir un string en variable numérique
, return true si la variable est numérique
calcrun.cpp
Le calcul exécuté toutes les 10 msec.
Ceci est la transposition de calc.c (V2).
Utilise mixer.cpp pour
le mélangeur courbe.
calchw.cpp
On trouve ici la gestion
des variables hardware en input et aussi le paramétrage pour un émetteur
- hwinit définit la variable dans la table (les variables hardware sont
des variables "input" mais qui existent toujours; elles n'ont pas à être
déclarées en output. Ceci est exécuté lors du chargement d'un modèle.
- hwread() lit les périphériques et met le résultat de la mesure dans
ces variables. Ceci est tout à fait dépendant du microprocesseur, du
hardware annexe (ADC en SPI par exemple) et de l'affectation des portes(
le cablage)
Comme le MBED est programmé très facilement, l'adaptation des paramètres
se fait directement dans ce programme source et ceci devrait être
facile, même pour celui qui ne sait pas programmer en C / C++.
Les entrées digitales connectées au Lcd sont lues indirectement à partir
d'une table dans l'objet Lcd4D.
- Pendant le redémarrage le Lcd est bloqué et ne peut pas lire les
entrées digitales. Cette table est préservée par le watchdog.
- hwout() est exécuté après la boucle de calcul pour coder les voies de
sortie. Pour le moment seul le mode PPM est programmé, mais un autre
mode de transmission n'exige qu'une modification de cette fonction.
Fonctions temps réel
Les besoins sont relativement simples et ne justifiait pas un RTOS
-génération du signal PPM , avec une précision d'ordre de la microseconde
-exécuter toutes les 10 msec la boucle de calcul
-gérer les transmissions avec l'écran sans bloquer les calculs
-exécuter les dialogues, les menus...
Par contre l' acquisition de la télémétrie Jeti aurait été plus aisée avec
une tâche séparée et donc un RTOS.
La difficulté se trouve dans le démarrage:
- le mode de démarrage normal (coldstart) n'a pas de contrainte de
temps. On allume l'émetteur, on vérifie le nom du modèle, l'émetteur
vérifie les positions de démarrage de certains organes de commandes , et
ensuite seulement on allumera le récepteur
- le redémarrage après intervention du watchdog (warmstart) doit se
faire aussi vite que possible, sans vérification de démarrage
- le lcd démarre lentement mais est utilisé pour lire les positions des
interrupteurs et pour émettre des messages d'alarme
La cause du démarrage se trouve dans un byte préservé lors du redémarrage
(rc.startmode)
0 = démarrage normal après
power-off
1
= redémarrage volontaire ( par exemple pour effacer les "memory
leaks" éventuels). Il ne faut pas redémarrer le LCD.
2 = redémarrage après erreur LCD (NAK answer)-restart LCD
3 = bloquage détecté par le
watchdog , qui joue ici son rôle normal
Pour le moment on utilise seulement les valeurs 0 et 3 , les conditions 1 et
2 provoquent 3
L'état du Lcd : (rc.lcdstate)
2 = démarrage achevé :une utilisation complète est permise
1 = disponible pour la lecture des entrées digitales dans l'état qui précède
le warmstart
0 = non disponible
Le programme principal est rccl_dialog, qui exécute l'un des menus.
Chaque menu se termine par le return d'un code (voir enum dialog) qui
désigne le menu suivant. Ceci tourne sans fin en rond, en attendant une
sélection par touchscreen. La fin est par le menu de power-off.
Les programmes "temps-réel"sont appelés par rc_task(x). C'est une
version très simplifiée d'un RTOS.
Ce task-switcher est appelé lorsque le programme attend un
évènement :
- rccl_task(0) attente d'une réponse de la communication série avec le
lcd,le plus souvent rapide mais une durée longue est possible (change
background = près de 3 secondes ou initialisation du lcd)
- rccl_task(1) attente d'une réponse de l'opérateur humain
(touchscreen), ou éventuellement une commutation de tâches dans un
traitement de longue durée
- rccl_task(2) attente d'une réponse de Jeti
La génération PPM se fait avec les interruptions d'un timer. Le plus facile
est d'utiliser la library MBED, mais il est possible de s'en passer et
d'utiliser un timer spécifique, différent du timer 3 utilisé par mbed.
programme principal (rccl.cpp)
Ce programme est la boucle principale (le programme main du microprocesseur)
L'initialisation rccl_init()tient compte du mode de démarrage ( normal
ou après intervention du watchdog). Le fichier RCCLINIT comporte le nom du
modèle courant. Ce modèle est immédiatement chargé , le signal PPM est
activé et l'émetteur est en fonction après 0,5 sec.
Pendant l'initialisation du lcd, l'émetteur doit fonctionner normalement
mais ne répond pas à une modification d'un interrupteur.
Ensuite, le menu principal est appelé: rccl_dialog(), voir menu.cpp.
C'est une boucle perpétuelle; chaque menu renvoie le code du menu suivant.
Le menu initial dépend de l'état :
- si au démarrage le nom du modèle courant est inconnu ou si ce fichier
n'existe pas:
- si le chargement du programme échoue (fautes) :
- si le modèle est chargé , ce qui est le cas normal :
paramètres mis à jour en vol, trims
Ceci est un aspect important pour l'utilisateur.
- inter à 3 niveaux de trim (gestion par hwread)
- dtrim_level normal = 0 (position centrale)
Le bouton Autotrim est désactivé (@BA toujours faux) et disponible
pour d'autres usages (@BB)
Trims digitaux actifs
- dtrim_level 1 = trim initial rapide
Le bouton autotrim @BA est actif . Remarquez qu'il est traité pour
empêcher les rebonds et qu'il n'est mis à "true" que pendant un seul
cycle de calcul.
Trims digitaux actifs
- dtrim_level 2 = trim des paramètres
Les trims digitaux sont affectés à des paramètres et ne servent donc
plus à trimmer les manches
Le bouton Autotrim est désactivé (@BA toujours faux) et disponible
pour d'autres usages (@BB)
- objet DTRIM
- un objet dtrim est créé par trim digital"hardware" (array dans
l'objet calc, créé par hwinit)
get(b1,b2) enregistre l'état des boutons et met le paramètre à
jour (appel dans hwread );éventuellement signale un "clic"
putpvar(x , level) enregistre le paramètre pvar connecté (1 par
level)
- calcrun calcload de DTRIM
- param :save des fichiers de paramètres modèle.mdp
Le format de ce fichier mdp doit être compatible V2/V4 .
V2 = 2 50 -10000 afL.U: soit 2 index valeur nom vvar, seuls les
deux derniers sont utilisés par le simulateur
V4 = 4 0 -10000 afL.U: adapter calc.py line 865
et 5 1 pvar:: pour l'affectation à
un DTRIM
les fichiers comportant les paramètres de l'émetteur
La situation actuelle est:
Snd :sound.cpp et sound_xx.cpp
L'objet Lcd4D fournit les accès de base aux fichiers sons de la carte SD(
voir plus haut :play(filename) pour jouer un fichier son et
getSoundLen(filename) pour en connaître la longueur.
Ces fonctions sont codées dans le programme sound.cpp
L'objet Snd est codé dans sound.cpp . Ce programme comporte toutes les
fonctions indépendantes de la langue.
Le fichier sound_xx.cpp comporte les quelques fonctions qui dépendent de la
langue xx
L'objet Snd comporte une file d'atttente FIFO avec les noms des fichiers à
jouer , ou les silences.
Les fonctions programmées dans sound.cpp sont:
- constructeur d'un objet Snd
- xput,nput,zput -> ajoute un fichier son en fin de table
- getNext-> exécuté de façon répétitive, émet le son suivant dès que
le son en cours a atteint sa durée
- putVar dicte une valeur numérique < 1000, avec le choix du nombre
de décimales après la virgule. Cette fonction est programmée dans
sound_xx pour disposer de programmes différents selon la langue.
Le programme sound_fr comporte la conversion de nombres en sons, ici
pour une conversion en français.Un "#define" spécifie le mode français ou
belge.
Pour adapter la langue de l'émetteur il suffit de recompiler RCCL. Il faut
également remplacer les fichiers son de la carte SD.
développement des messages (chr, show, play,break) voir rccl
Affichage
Le programme de calcul prépare les données à afficher sous la forme d'une
table lcd[8], qui se trouve dans l'objet Calc. Cette table est mise à jour
par chaque cycle de calcul.
Les menus de dialogue comportent un "menu_normal.cpp" qui est celui qui
s'affiche en temps normal, lorsque le pilote ne manipule pas l'écran.
Ce menu prépare 8 zones de texte qui sont des objets graphiques Grt. Ils
portent également le nom lcd[ ] mais ils sont définis dans le menu.
Les deux première lignes sont de petite hauteur, la dernière est de couleur
rouge .
En permanence, le programme "menu_normal" copie le string lcd vers l'élément
graphique lcd . Notons que si le string ne change pas ceci ne réécrit
pas l'écran (pas de flicker).
L'affichage utilise les instructions RCCL CHR, SHOW et BREAK
Messages
sonores:
Des messages sonores sont définis par le modéliste . Il crée les fichiers
xxx.wav sur la carte SD du lcd , puis utilise ce nom de fichier dans des
instructions RCCL.
L'instruction BREAK est particulière: elle est réservée aux contrôles au
moment du démarrage.
Les instructions BREAK ne sont pas traitées en cas de redémarrage après
intervention du watchdog.
L'écran affiche le mesage d'une instruction BREAK à la fois
Quant une instruction BREAK est exécutée, elle affiche son message en
dernière ligne de l'écran , fait sonner une alarme et un message standart et
n'exécute pas les instructions suivantes.
Lorsque la condition d'erreur est corrigée, les instructions suivantes snt
exécutées et éventuellement une nouvelle ligne BREAK.
sons pour le vario
La variable de télémétrie est exprimée en m/sec.
Un mélangeur non linéaire transforme cette variable en tonalité. Pour tenir
compte des valeurs autorisées pour les variables, la tonalité est un nombre
égal à la fréquence / 40 .
Ensuite l'instruction PLAY en format 8 (vario) appelle le fichier son qui y
correspond. Ce fichier est de la forme VVffff.WAV, fff étant la fréquence.
Pour générer ces fichiers, on utilise sous Linux la commande tones du
package siggen
Voici un petit script qui génère les fichiers de 400Hz à 2200Hz (j'utilise
Linux)
#!/bin/bash
# tones files
for (( c=400; c<=2200; c=c+40 ))
do
echo "Tones $c Hz..."
tones -w VV$c.wav -s 16000 -16 200 $c
# variable c = frequency in Hz
# wav file name VV..
# 200 = duration in msec
done
interface JETI
hwjeti/jeti.cpp
la communication entre module Jeti et JetiBox se fait à 9600 Bauds, avec des
caractères de 9bits +parité + 2 stop bits, qui n'est pas possible pour
l'UART du mbed. Il faut donc une autre solution, par exemple un UART
software.
Cette routine gère un UART software pour des messages "reçus" de
32 caractères, un message émis a un seul caractère.
La routine s'inspire de la note AVR 274,pour réaliser une lecture UART
en utilisant des interruptions.
Le buffer mis à la disposition des programmes comporte 32 bytes, les 2lignes
de 16 bytes de la JetiBox.
hwjeti/menu_jeti.cpp
JetiBox "active"
Le menu affiche le message courant et propose des boutons
(flèches) pour les actions possibles, y compris un bouton pour actionner
simultanément deux touches (fonction Erase).
Le mode de détection tacile est
-normalement "One Touch" = une seule transmission vers le module Jeti
-ou bien "Long Touch"= transmission en rafale, tant que l'on appuie sur une
touche
En complément on utilise les fonctions décrites ci-dessous pour déterminer
le code du nœud affiché et en extraire les variables.
JetiBox passive
Ce menu affiche les messages de la JetiBox sans interférence, il est utile
pour contrôler la navigation automatique.
hwjeti/explorer.cpp
Ceci est le programme de navigation, qui est relativement complexe
car si le protocole Jeti est bien adapté à un dialogue avec l'utilisateur il
n'est par contre pas du tout adapté à une communication entre programmes.
De plus, cette navigation est lente et RCCL V4 a été écrit sans RTOS ce qui
impose une navigation "non transactionnelle" et un certain nombre de
variables d'état.
- explorer_load() charge en
mémoire le fichier de navigation , immédiatement avant chargement du
modèle, qui corrigera les lignes de l'xpander (instruction JETIX)
- explorer_connect() explore
les menus Jeti pour déterminer ce qui est connecté puis introduit ces
connections dans la copie du fichier de navigation.( voir lin() et
linkL() )
- readMap recherche le chemin
qui mène d'un nœud à un autre (du nœud actuel au nœud qui comporte la
variable recherchée).
Cette fonction est appelée répétitivement après chaque étape, car entre
deux étapes la transmission pourrait décrocher. Elle renvoie la
direction à prendre à partir du nœud courant et le numéro du nœud
suivant, ce qui définit le pas suivant.
- getVar recherche une variable
sur l'écran et la convertit en nombre
- JetiSensor est appelé dans la
boucle de calcul pour exécuter une instruction Jeti.
A tout moment il y a au plus une ligne JETI qui est active ( défini par
iop_busy) . Elle progresse pas à pas de sa position courante vers le
nœud "destination".
core/calcrun.cpp
- l'instruction JETI appelle JetiSensor - la séparation tient compte des
classes différentes Jeti et Calc
- il y a un traitement spécial de l'instruction JETI avant toute
sélection par les instructions IF / ENDIF. Le but est de mémoriser la
variable de sortie pendant un certain temps.
Pour cela, chaque instruction comporte deux paramètres internes: la
valeur et sa durée de validité.
Images
Pour afficher les textes et les images en mode landscape, il faut à la fois
(très troublant !)
- une configuration DISP adaptée au mode Landscape et utiliser
l'utilitaire DISP pour changer le firmware
- les instructions d'initialisation en mode landscape
Logging
le logging se fait vers la carte SD du LCD, et ceci est délicat car la
voie de communication est encombrée, principalement par la lecture des
entrées digitales.
Le programme de calcul écrit un message de logging dans une file
d'attente, si deux conditions sont remplies:
- les données de télémétrie ont été rafraîchies (toutes les 80 msec
environ)
- la file d'attente n'est pas trop grande
Les messages sont écrit vers la carte SD par rccl_task, lorsque c'est
possible.
La transmission se fait à 282353 bauds (cette valeur bizarre est une
anomalie dans 4D) soit à environ 31 bytes/msec.
Watchdog
implémenté.
Pendant le redémarrage du LCD, on n'a pas accès aux digital inputs du lcd.
Leur état est cependant restauré.
to do
- copie d'un fichier sous un nouveau nom
- editeur avec copy/paste d'un token
- préprocesseur avec code pour lignes réservées à une version
#2 remplacé par deux espaces si version 2
#4 remplacé ( réalisé en version 4)
to do power
- watchdog en distinguant
- soft reset sans redémarrage 4D
- soft reset avec redémarrage 4D (après NAK)
- watchdog après lock d'origine indéterminée
évolutions futures envisagées
- remplacer les entrées digitales du Lcd par un chip SPI
-> accessible dès le démarrage
-> mettre le 4D en sleep pndant le vol, pour diminuer la consommation
et cei rend inutile l'amplificateur séparé sur la carte 4D
- rendre les pins SPI accessibles, par exemple pour connecter une carte
SD
Retour au sommaire
©
Copyright 2008-2012 Robert Spilleboudt - Tous droits réservés.
Projet rcopensource -
Licence GPL V2