Général Généralités sur les variables, librairies, ... pour les débutants

  • Auteur de la discussion gégé62
  • Date de début
gégé62
gégé62
Compagnon
26 Fev 2013
2 988
Harnes (Pas de Calais)
  • Auteur de la discussion
  • #1
Bonjour à tous,
Ce poste pour y rassembler les informations intéressantes exposées ça et là dans les posts de la rubrique Arduino de notre forum.
Pour qu'ils nous aident, nous débutant dans la programmation de l'Arduino.




je n'ai pas encore bien l'habitude de programmer..
je vois que tu mets 2 fichiers séparés "CONFIGURATION_H3 ET "PINS_H"
C'est pour alléger l'écriture du fichier principal ?
 
Dernière édition par un modérateur:
?
******
Compagnon
6 Jan 2014
2 881
paris
Bonjour gege
oui ,
J'ai copier cette technique sur le programme des imprimantes 3D "marlin"
c'est pas tres academique je pense...

mais ca marches ,

les choses sont plus claire et ca facilite grandement les choses en fin de compte.


Amicalement

jc
 
usitour
usitour
Compagnon
13 Oct 2015
1 202
FR-29 Brest
De plus tes fichiers de configuration peuvent être utilisés dans d'autres programmes
c'est comme les librairies toutes faites qui servent à bon nombre de programmeurs.
Il me semble qu'il existe un fichier pour piloter les afficheurs en spi.

Cdlt
 
lion10
lion10
Compagnon
7 Mai 2010
4 752
Bonjour
Les ".H" sont soient crés par l'utilisateur ou fournis en tant que modèle modifiable avec les kit de développement ou fournis avec des bibliothèques.
C'est en quelque sorte une définition des broches du composant par exemple pour un pic24xxx ou un pic 18xxxx.
Ils peuvent aussi contenir des types de variables ou des prototypes de fonction par exemple.

Dans un ".h" par exemple on indique que la fonction f(X,Y) renvoie Z entier et accepte X et Y de type float . On peut aussi y rajouter un commentaire sur l'utilisation de cette fonction.
Ensuite lorsque qu'un utilisateur utilise cette fonction il faut juste qu'il fasse une inclusion de ce ".H" . Je précise utilisateur car il faut aussi voir cela dans un gros projet avec plusieurs développeurs. En appelant cette fonction si on fait une erreur en lui transmettant un paramètre qui n'est pas un entier (je ne parle pas des cast) le compilateur génère un warnning ou une erreur selon le cas.

Pour une bibliothèque c'est le moyen de dire comment utiliser les fonctions qui y sont codées tout en préservant le contenu détaillé qui peut être le fruit de longues heures de développement, le savoir faire qu'il ne faut pas diffuser.

cdlt lion10
 
?
******
Compagnon
6 Jan 2014
2 881
paris
@ lion10, merci pour votre explication ,

dans les points h que j'ai creer, je n'ai pas vraiment réussis a déclarer les variables correctement

et quand je les declare de facon manisfeste , le compilateur refuse de travaller ...

alors la vous avez en presence (ds les point H) des variables floues... mais ca marche ..

et comme la technique est copier d'un programme serieux (Marlin-pour imprimante 3D- ) en tout les cas

qui a fait ces preuves .

c'est pour cela que je trouve que ce n'est pas accademique ...


@usitour

S'il vous plais usitour que voulez vous dire par spi avez vous des liens pour se documenter sur le sujet?





Amicalement

jc
 
?
******
Compagnon
6 Jan 2014
2 881
paris
Merci Beaucoup !!!

Bonne journée !

jc
 
lion10
lion10
Compagnon
7 Mai 2010
4 752
bonjour
dans les points h que j'ai creer, je n'ai pas vraiment réussis a déclarer les variables correctement
et quand je les declare de facon manisfeste , le compilateur refuse de travaller ...
Normalement une variable est mise dans un fichier ".c", une fonction c'est pareil et elles y sont décrites en détail.
Dans le fichier ".h" vous déclarez la variable en tant "extern" et faites de même pour une fonction, puis c'est ce fichier ".h" que vous mettez en "include" dans chaque fichier ".c" utilisant ces ressources.
Le fait de déclarer la variable dans un ".c" c'est ce qui va concrètement réserver une case mémoire dans le micro-contrôleur. En fonction de ce que vous mettez comme déclaration cette variable plus ou moins complexe peut se retrouver par exemple dans une case de mémoire vive ram, dans une case de mémoire eeprom ou dans une case de mémoire flash du micro-contrôleur. Cela a donc de l'importance puisque une variable déclarée en "const" est placée dans la mémoire flash et ensuite il est impossible de la modifier dans le logiciel, c'est une constante.

En déclarant une variable dans un ".c" à part appelée en "extern" par un ".h" vous jouez aussi sur la portée de la variable, ce qui est important dans certains cas. Une variable en globale nommée est modifiable dans toutes les fonctions qui l'utilisent, si elle est locale à un fichier elle cesse d'exister et sa valeur est perdue (sauf static) lorsque votre logiciel exécute une fonction placée dans un autre ".c".
(Je ne parle pas de l'assembleur mais des principês similaires existent.)

Dans un compilateur des mots clés spécifiques sont inclus dans la documentation pour dire au développeur ce qu'il doit mettre dans le logiciel s'il veut dans une application particulière que telle donnée soit placée à une adresse particulière ou une partie qui sera remise à zéro à chaque démarrage du logiciel. Mais là on se dirige vers des possibilités dont vous n'aurez normalement pas besoin, logiciel rapide, optimisation des temps d'accés aux variables, séquence de démarrage à froid maîtrisée, accès au bus d'adresse du micro-contrôleur en externe quand c'est possible pour y adjoindre de la mémoire supplémentaire en maitrisant le mapping d'adressage des composants ou tout autre dispositif plus ou moins complexe.
Pour aller encore plus loin, il faut voir les directives du compilateur et de l'éditeur de lien mais je ne sais pas si l'environnement de développement logiciel ARDUINO permet de telles possibilités, je pense que oui mais elles doivent être dans la partie immergée afin d'être invisble au premier coups d'oeil pour simplifier l'interface pour l'utilisateur amateur.

cdlt lion10
 
gégé62
gégé62
Compagnon
26 Fev 2013
2 988
Harnes (Pas de Calais)
  • Auteur de la discussion
  • #9
c'est bien d'être à l'aise avec tout ça.....:???:
 
gégé62
gégé62
Compagnon
26 Fev 2013
2 988
Harnes (Pas de Calais)
  • Auteur de la discussion
  • #10
Une seconde lecture (de lion10) à tête reposée m'a permis de mieux saisir et donc conforter mes connaissances au sujet de la portée des variables (les deux premiers §).
Bien utile quand on pratique l'Arduino...merci !
 
?
******
Compagnon
6 Jan 2014
2 881
paris
Bonsoir, la question des variable et arduino a beaucoup d'importance
et connaitre les notions de programmation :
.ccp
.h
.c
.ino
et de bibliothèque permettent de faire des miracles !
(sans oublier les pointeurs)

Personnellement je fait de l'informatique ( de la programmation ) de toute sorte depuis 30 ans de façon 'tres peu professionnel'. Et pour ajouter au désastre, pendant deux ou trois ans je n'en fait pas ... puis pour quelques motifs très différents a chaque fois je mis met :
alors des fois et en fonction des modes et des années ::
Du Basic
de l'assembleur
du lisp
du cobol
du pascal
du java
... du c du c plus plus ...
Je bricole tout le temps ...
et aussi python, applescript , javascript , php , html ...... AAAAAAA :)
tiens par exemple je monte un programme qu'avec "des flags", "des drapeaux", "des aiguillages. Comme quelqu'un qui monterai un circuit de rail de train (jouet).
En faisant cela sur le champs ....tout ce qu'il ne faut pas faire ....
Le contraire d'un langage objet structuré ....ARRRG les mauvaise habitude du début de l'informatique me colle a la peau.
Apres seulement je met tout en ordre .... et en essayant d’être le plus académique possible ..

Amicalement

jc

PS : pour Aduino
il est déconseiller d'utiliser les "float" .....
Mince il vas falloir que je trouve un remède a mon programme .
Mais en même temps il fonctionne comme je le souhaite !!
Alors quoi !!! hein !!! Bon :) :)

PS1:
J'ai un problème avec le filtre numérique a cause de la cacophonie
lieé a la non maîtrise du type de variable dans ce dernier programme ... aussi
Mais c'est l’occasion d'une nouvelle version et puis je prétend pas faire un
truc de pro pour l'industrie , ca me donne une largesse et liberté.
Et bien sur ca n'est jamais optimisé !!
Tout le professionnalisme est :
l'optimisation et la suprême garantie de la stabilité du programme
soit ::
la gestion des erreurs possibles !!

PS2 : saviez vous que dans certain programme la gestion des erreurs
contiens plus de code que le programme lui-même.

Saviez vous que linux par exemple a tres peu de gestion d'erreur possible d'un utilisateur lambda .
 
Dernière édition par un modérateur:
gégé62
gégé62
Compagnon
26 Fev 2013
2 988
Harnes (Pas de Calais)
  • Auteur de la discussion
  • #12
mince, tu ne te mélanges pas avec toutes ces programmations différentes ?
C'est peut-être comme les langues étrangères, plus on en connait, plus on en apprend facilement d'autres (enfin il parait....:-D )
Mais il y a tellement de subtilités dans la syntaxe, pour l'instant j'essaie le C, c'est déjà bien complexe. Une question: pourquoi faut-il tant de langages différents ? je comprends bien qu'on ne peut pas tout faire avec un seul langage, mais dans tous ceux que tu cites il doit bien y avoir du double emploi ?
Actuellement j'essaie de comprendre les pointeurs, c'est la m..., et surtout je ne comprends pas bien dans quel cas on a intérêt à les utiliser.

Saviez vous que linux par exemple a très peu de gestion d'erreur possible
d'un utilisateur lambda
je te crois sur parole...:P
quand je pense que mes deux fils travaillent dans l'informatique...mais ils sont loin, alors pas facile d'aider leur vieux père...
 
?
******
Compagnon
6 Jan 2014
2 881
paris
Bonsoir Gege,

Je ne prétend pas faire le prof la mais, en gros, il existe :

1- le langage "Machine" (Assembleur)
tu codes directement le processeur
pour ma part :
https://fr.wikipedia.org/wiki/Zilog_Z80
mais c'est très vieux n'est ce pas
Donc tu vas directement écrire dans le registre du microprocesseur.
c'est assez épique.

2- les langages "Interpretés''
Un interpréteur se distingue d’un compilateur par le fait que, pour exécuter un programme, les opérations d’analyse et de traductions sont réalisées à chaque exécution du programme (par un interpréteur) plutôt qu’une fois pour toutes (par un compilateur).
https://fr.wikipedia.org/wiki/Interprète_(informatique)


3- les languages "Compilés"

Bref, après les différents langages dont j'ai parlé, s'inscrive dans une espèce "d'histoire naturelle" des langages disparaissent d'autres aparraissent pour diverses raisons.
Parfois c'est une la compétition de deux langages pour des raison seulement Economique (Pascal VS langage C)
Parfois c'est pour des raisons de concepts. Certains étant vraiment meilleurs... bon et cette histoire naturelle aujourd'hui en est a :
Langage C , C ++ et les dérivés comme Java (arduino), et des langages de scriting (langage "super interprété" espèces récentes de macro langage liée a la puissance des nouvelles génération de machine): Python , javascritp ... et d'autre qui son en compétition aujourd’hui.
Mais en gros le grand vrai survivant c'est le 'C'

A ce sujet un livre complet et excellent. Si tu connais ce livre tu connais les pointeurs et tout le reste.
1200 pages (en anglais)
Un sacrés pavé , mais super pour un débutant !!
Ivor Horton's
Beginning
Visual C++ 2010

Amicalement
jc
 
Dernière édition par un modérateur:
lion10
lion10
Compagnon
7 Mai 2010
4 752
bonjour
Actuellement j'essaie de comprendre les pointeurs, c'est la m..., et surtout je ne comprends pas bien dans quel cas on a intérêt à les utiliser
Le pointeur nommons le Y pour l'exemple est un type particulier de variable qui correspond à une adresse mémoire d'une autre variable X. Pour l'initialiser on affecte donc à la variable Y pointeur, l'adresse mémoire de cette variable X.

L'interêt du pointeur c'est qu'il permet de passer en paramètre par exemple l'adresse mémoire d'une table ou plus compliqué d'une structure complexe de données.
En passant en paramètre l'adresse si l'on sait quelle est la variable qui est pointée, on sait comment elle est organisée et comment y accéder ensuite. Il faut aussi savoir sa taille pour un tableau.
En passant un pointeur en paramètre cela permet d'éviter le passage d'une valeur (typiquement une structure) qui peut être encombrante alors qu'un pointeur fait typiquement 4 octets en terme de taille. Cela est indispensable avec des micro-contrôleurs qui n'ont pas forcément beaucoup de pile.
Mais surtout si on considère une fonction ou une procédure les paramètres sont passées par valeur ce qui les protègent mais ne permet pas de les modifier, dans certains cas particuliers en passant l'adresse on peut donc aller modifier l'objet pointé qui est le paramètre qui est fourni.
Pour des cartes à micro-contrôleurs complexes des périphériques sont reliés sur le bus d'adresse du micro le hardware fixe l'adresse, le logiciel ensuite y accède par l'intermédiaire d'un pointeur.
On peut aussi cas beaucoup plus compliqué, je ne suis pas persuadé que l'arduino le permette, avoir des pointeurs non pas sur une variable mais sur une fonction. Cela permet par exemple de faire une action particulière en fonction d'une valeur du logiciel. Pour faire un automate par exemple, si on appuie sur la touche avance rapide on doit exécuter l'action décrite dans la fonction avance rapide, de même si on appuie sur d'autres touches on affecte d'autres opérations. L'automate consiste alors à réaliser une fonction pointée différente (récupérée dans une table) en fonction de la valeur d'une touche.
Des pointeurs en les incrémentant permettent de faire par exemple des boucles de recopie de tableau, accéder à des tableaux multi dimensions. On peut aussi pointer un pointeur, comparer des pointeurs, faire des tableaux de pointeurs. (Une chaîne de caractères est un tableau avec 0 dans la dernière case, un tableau de pointeur peut s'initialiser avec plusieurs chaînes de caractère, les jours de la semaine par exemple.)

Pour revenir sur des applications basiques du pointeur :
int X,Y; //variables déclarées et réservées en mémoire
int *point; // déclaration du pointeur mais il ne pointe sur rien et ne réserve pas de place pour ce qu'il va pointer plus tard !

X=2;
point = &Y; // point pointe sur l'adresse de Y
*point = X; // la valeur de X est affectée à l'adresse pointée soit à Y
point +=1; // le pointeur est incrémenté dans le cas présent, bug potentiel l'objet pointé est incertain

Pour un tableau :
------------------------
int tableau[10];
int *point;
point = &tableau[0]; // point pointe sur le premier élément du tableau
point = tableau; // idem ci dessus
*(point + 2) = 44; // le 3 élément du tableau est initialisé à 44.
*(point + 9) = 56; // le dernier élément du tableau est initialisé à 56
*(point +10) = 100; // bug on accéde à une variable autre dans le logiciel mais plus dans le tableau, il faut toujours avoir en tête la taille du tableau pointé
point +=9;
*point +=4; // le dernier élément du tableau passe à 60
point--;
*point = 33; // l'avant dernier est initialisé à 33


cdlt lion10
 
Dernière édition:
?
******
Compagnon
6 Jan 2014
2 881
paris
Salut lion10

Comme Arduino et basé sur Java et que java est base sur C++, Java utilise aussi des sortes de pointeurs ...
Arduino a certainement les limitations... mais je ne vois pas trop clairement quoi ...
http://limos.isima.fr/~toussain/doc/Diff_C++_Java.pdf
--------------

Dernierement j'ai crus comprendre que maintenant

l'histoire naturelle de la programmation tire a un laisser de coté de la question des pointeurs

(il me semble ...)

avec l'arrivée du langage "dérivé" de C + + qui s'appel

C# (C dieze)


maintenant on peu lire :

'tu peu tres bien utiliser les pointeur avec C# mais ce n'est pas conseiller ....


.

avec C# :
--> les pointeurs c'est bien pour .. des masses importante de calculation

quand l'ordinateur ....rame..... a force de lui demander des choses.

--(mais aujourd'hui il faut le vouloir pour faire ramer un ordi
a part si on travaille pour une entreprise de statistique ou je ne sais quoi
d'un accelerateur de particule ou ...autre ...

Mais en tant que personne qui fait une recherche personnelle
ou meme une entreprise courante,
c'est ... difficile ou tres rare en utilisation normale de faire
ramer un ordi . Ordis qui sont aujourd'hui incomparablement plus puissant qu'il y a ne serait ce, qu'il y as 15 ans ..

bon...

JE continue avec mes aiguillages (des pointeurs d'une certaine maniere)



ET merci Lion10 pour ton explication des pointeurs !!


Bien a toi

Jc
 
Dernière édition par un modérateur:
gégé62
gégé62
Compagnon
26 Fev 2013
2 988
Harnes (Pas de Calais)
  • Auteur de la discussion
  • #16
@jicer
@lion10

merci à vous.
En fait, bien sûr, j'ai déjà lu tout ça (sinon il aurait été indécent de ma part d'aborder le sujet ainsi...:wink: ) Je lis actuellement un livre de "C" (1990) retrouvé au grenier, qui appartenait - qui appartient d'ailleurs ! - à l'un de mes garçons. Donc je suis sur les pointeurs en ce moment....

En fait je crois que , comme souvent, la connaissance doit venir avec la pratique. J'ai beau lire 20 fois les mêmes choses, ça ne rentrera pas si je ne mets pas en application, donc....faut que je me mette à l'eau...

Quelques questions précises:
point = &tableau[0]; // point pointe sur le premier élément du tableau
est-ce c'est la même chose de dire: "la variable point est l'adresse du premier..."
alors qu'un pointeur fait typiquement 4 octets en terme de taille.
c'est en rapport avec la taille de la mémoire je suppose (de toutes les mémoires cumulées), qui détermine le nombre d'adresses possibles ?
4 octets = un peu plus que 4 Giga d'adresses possibles
par contre tu définis
int *point; // déclaration du pointeur
ce qui fait 2 octets (enfin avec Arduino) mais qui est limité à 65536 adresses. Par contre avec 4 octets, c'est > 4 Giga. Donc pour les "petits" micro controleurs (Arduino, 32 k) "les pointeurs en int" suffisent, pour les "gros" PC, il faut 4 octets (unsigned long ?) ?

merci
 
lion10
lion10
Compagnon
7 Mai 2010
4 752
Bonjour
est-ce c'est la même chose de dire: "la variable point est l'adresse du premier..."
Oui dans les faits après l'affectation, d'allleurs j'ai mis en dessous une autre possibilité. Le "&" est l'opérateur qui prend l'adresse, le [0] correspond à la première adresse. Bien entendu avec [1] vous n'êtes plus au début mais c'est aussi possible.

c'est en rapport avec la taille de la mémoire je suppose (de toutes les mémoires cumulées), qui détermine le nombre d'adresses possibles ?
4 octets = un peu plus que 4 Giga d'adresses possibles
J'ai mis 4 octets mais en pensant à une l'application avec un micro-contrôleur qui avait 32 fils d'adresses.
Il faut considérer ce que permet le standard C Ansi, ce que permet le compilateur et ce que permet l'adressage mémoire du micro. Normalement les 2 derniers sont en phase c'est donc le compilateur qui dicte ces considérations avec des limitations. Il faudrait voir si "size of" est utilisable avec arduino , il permettra d'avoir une confirmation par l'expérimentation de la taille du pointeur. On arrive aux frontières entre le matériel et le logiciel, là il faut être prudent si par exemple on veut faire un logiciel qui fonctionnera partout sans modification, pour des applications poussées on pourra utiliser de la compilation conditionnel et des "size of".

ce qui fait 2 octets (enfin avec Arduino) mais qui est limité à 65536 adresses. Par contre avec 4 octets, c'est > 4 Giga. Donc pour les "petits" micro controleurs (Arduino, 32 k) "les pointeurs en int" suffisent, pour les "gros" PC, il faut 4 octets (unsigned long ?) ?
Il faut bien distinguer la taille du pointeur permise par le compilateur de la taille de l'objet pointé.
Dans l'absolu si vous n'avez que 12 cases de 8 bits de large dans un micro le compilateur va sans doute limiter la taille du pointeur à un octet, mais 12 cases permettent de caser 12 variables de largeur 8 bits , mais aussi 6 variables de largeur 16 bits ou 3 de largeur 32 bits. Dans le premier cas quand vous incrémentez le pointeur il est juste augmenté de 1, mais dans le second il est augmenté de 2 et dans le dernier cas il est augmenté de 4, En effet selon la taille de la variable passer à la suivante c'est faire un saut plus ou moins important dans les cases mémoires.
Là encore il faut voir ce que permet le compilateur de l'arduino il peut aussi interdire certains types de variables ou s'écarter du C ansi et ne pas différencier 2 types de variables (float ou double à voir...) ou leur attribuer un nombre d'octets particulier.
On voit à travers l'exemple ci dessus que forcément la taille figée en dur dans le micro 8, 16 bits ou 32 bits par exemple fera qu'il sera faible puissant ou mauvais pour faire des calcul sur des variables longues.
Attention la taille d'un pointeur est la même pour des variables de type différents, mais il ne faut pas utiliser directement, sauf à savoir ce que l'on fait, un pointeur sur int pour pointer un char, sinon on saute des valeurs à chaque incrémentation du pointeur. (L'usage de cast devrait pouvoir se faire mais c'est une utilisation plus spécifique.)

Ps : Il faut signaler aussi l'utilisation des pointeurs pour des listes chainées et dans l'allocation mémoire dynamique.

cdlt lion10
 
gégé62
gégé62
Compagnon
26 Fev 2013
2 988
Harnes (Pas de Calais)
  • Auteur de la discussion
  • #18
merci, je vais méditer tout cela tranquillement....
ça mérite une impression papier, tant pis pour l'effet de serre....:wink:
 
jpbbricole
jpbbricole
Compagnon
26 Mai 2016
2 266
Corsier-sur-Vevey (Vaud)
est-il abusé de te demander, si tu en as le temps, de mettre des commentaires sur les lignes de programmation
C'est certain que les commentaires sont super importants dans un programme mais, un choix judicieux de nom de variable peut aisément remplir ce rôle, ainsi

int v; // Valeur lue sur le potentiomètre A
commentaire qu'il faudra répéter à chaque usage de la variable v.

int valeurPotentiometreA;
le nom de la variable est suffisamment explicite pour éviter de la commenter et le programme est directemement lisible.

Et celà ne coûte pas un octet de plus dans l'Arduino.

Evitez les noms "plats",valeurpotentiometreaest moins lisible quevaleurPotentiometreA.


Bonne journée

jpbbricole
 
Haut