Aide Aide programmation Arduino

V

Vik'TheBike

Nouveau
18 Jan 2024
22
Agonac
Une question pour la gestion de tempo sans utilser l'instruction 'delay' mais avoir qqch d'assez simple dans le programme...

On ne pourrait pas utiliser une fonction avec un paramètre d'entrée qui serait le temps en ms et un paramètre de sortie qui serait un bit à changer d'etat quand la tempo est finie...
Une sorte d'instruction 'MonDelay' mais qui ne bloquerait pas le uC dans une boucle d'attente inutile...
Je ne sais pas si je me fais bien comprendre...
L'idée etant de ne pas avoir ces longues phrases "if (preciousMillis-Millis < maTempo) {}...à tout bout de champ dans le programme principal... 8-)
Tu peux écrire une telle fonction, je pense que tu as les connaissances nécessaires.
Sinon tu peux rechercher une librairie qui propose déjà cette fonction, je suis sûr que ça existe quelque part.

edit : un indice, si tu lis l'anglais : https://playground.arduino.cc/Main/SketchList/#Timing_code
 
W

wika58

Compagnon
17 Déc 2006
12 756
FR-54560 Lorraine
Merci pour tes 2 réponses :smileJap:
 
W

wika58

Compagnon
17 Déc 2006
12 756
FR-54560 Lorraine
Et re une question sur la declaration des variables...:rolleyes::oops:

Dans le code ci-dessus,
...
int delayMilliSeconds(int timerNumber,unsigned long delaytime){
unsigned long timeTaken;
...
Là je suis un peu perdu...
a) un int devant une fonction
b) une declaration dans les paramètres d'entrée de la fonction
c) une declaration en début du code de la fonction...

:7grat::7hus5::smt100
 
F

furynick

Compagnon
29 Jan 2017
1 235
Portet-sur-Garonne
Par définition une variable consomme de la mémoire, même si c'est une constante.
C'est juste la durée de présence en mémoire qui va changer mais pour le moment tu n'as pas besoin de chercher à optimiser ta conso mémoire.

Pour du timing tu as grosso modo 3 solutions :
1. La fonction delay, extrêmement simple mais bloquant donc il ne se passera rien d'autre pendant ce temps (tu verras les interruptions plus tard)
2. Le delta de millis dans un if, comme tu l'as évoqué c'est assez lourd mais très efficace. Préfères toutefois inverser la logique pour éviter un calcul à chaque passage dans la condition : static unit32_t next = millis() + TIMEOUT; if (millis() >= next) {next += TIMEOUT;}, tu passeras dans la condition toutes les TIMEOUT millisecondes.
3. Les timers étant la solution ultime, c'est un peu comme une alarme, tu définis une fonction qui sera exécutée à intervalles réguliers. Un peu plus complexe à mettre en œuvre mais tu as l'impression que c'est magique. C'est le uC qui fait des choses tout seul.
 
  • Réagir
Reactions: wika58
F

furynick

Compagnon
29 Jan 2017
1 235
Portet-sur-Garonne
a) une fonction va obligatoirement renvoyer une valeur et cette valeur a obligatoirement un type. Lorsque cette valeur est de type void elle est obligatoirement vide (void en anglais).
Dans ce cas là fonction renvoie une valeur de type int et tu dois avoir l'instruction return en fin de fonction.
b) une fonction prend obligatoirement un ou plusieurs paramètres, tout comme pour le retour ça peut être un seul paramètre de type void (choix par défaut et implicite lorsque tu ne précise rien entre les parenthèses). Ici la fonction prend deux paramètres, ce seront des variables locales à ta fonction dont les valeurs auront été fixées lors de l'appel à cette fonction. Ça s'appelle le passage par valeur. Tu verras peut être le passage par référence plus tard.
c) c'est simplement la déclaration d'une variable locale à la fonction.
 
  • Réagir
Reactions: wika58
F

fredcoach

Compagnon
11 Jan 2013
1 452
Hautes Alpes
Par définition une variable consomme de la mémoire, même si c'est une constante.
Pas obligatoirement. Le compilateur peut décider de mettre la valeur de la constante comme paramètre de l'instruction qu'il écrit en assembleur, comme s'il s'agissait d'un nombre donné dans le source. Si tu écris var = var + 10, il ne va pas créer une variable pour y stocker la valeur 10. Il peut faire de même pour une const
 
  • Réagir
Reactions: Vik'TheBike
W

wika58

Compagnon
17 Déc 2006
12 756
FR-54560 Lorraine
Hello..
Bonne nouvelle...:roxxx:
J'ai enfin un contact avec un des profs de l'univ de Lausanne.
J'ai fouillé sur le site de l'univ et j'ai trouvé les adresses mail des 2 profs.
Je leur ai fait un mail cette nuit et ce matin j'avais une réponse de Mr. Nicoud... qui s'occupe plus de la partie théorique.
Il m'a répondu que Mr. Rochat allait me répondre pcq c'est lui qui s'occupe de la technique...

A suivre et bonne journée.
 
  • Réagir
Reactions: gégé62
F

furynick

Compagnon
29 Jan 2017
1 235
Portet-sur-Garonne
@wika58 : yep, c'est ça
@fredcoach : c'est assez complexe et ça dépend des mécanismes d'optimisation du compilo. Ceci dit, il y a deux façons de déclarer des constantes :
  1. #define VAR "valeur" - dans ce cas on est sûr que la mémoire dynamique ne sera pas utilisée mais ça peut poser problème car c'est le compilateur qui va déterminer le type de la variable s'il n'y a pas de distinction spécifique
  2. const uint8_t var = 8; - dans ce cas c'est une variable typée clairement identifiée, le compilateur décidera de comment stocker et utiliser la valeur
Il est préférable d'utiliser la deuxième notation pour éviter des problèmes de typage lors de la manipulation de cette constante avec d'autres variables.
 
F

fredcoach

Compagnon
11 Jan 2013
1 452
Hautes Alpes
@wika58 : yep, c'est ça
@fredcoach : c'est assez complexe et ça dépend des mécanismes d'optimisation du compilo. Ceci dit, il y a deux façons de déclarer des constantes :
  1. #define VAR "valeur" - dans ce cas on est sûr que la mémoire dynamique ne sera pas utilisée mais ça peut poser problème car c'est le compilateur qui va déterminer le type de la variable s'il n'y a pas de distinction spécifique
  2. const uint8_t var = 8; - dans ce cas c'est une variable typée clairement identifiée, le compilateur décidera de comment stocker et utiliser la valeur
Il est préférable d'utiliser la deuxième notation pour éviter des problèmes de typage lors de la manipulation de cette constante avec d'autres variables.
Tout à fait d'accord.
Tant que le compilateur allouait systématiquement de la mémoire pour une variable même constante, la première notation présentait un intérêt, au prix du risque d'erreurs potentielles. Maintenant que le compilateur peut décider de ne pas allouer de mémoire, la première notation ne présente plus d'intérêt et il faut clairement privilégier la deuxième.
 
5

59JAG

Ouvrier
7 Fev 2010
264
59 chti nord
moi j aime bien declarer des #define surtout pour faire des macro pour manipuler les bit sur le port
exemple: #define PIN_A1 ((PORTC &_BV(1)) >> 1)
 
W

wika58

Compagnon
17 Déc 2006
12 756
FR-54560 Lorraine
Oui ben ca c'est mon calvaire pour le moment... :hang:
Si tu pouvais un peu developper/expliquer ton exemple... :prayer:
 
Dernière édition:
S

speedjf37

Compagnon
15 Oct 2009
3 326
FR-37700
Bonjour,
moi j aime bien declarer des #define surtout pour faire des macro pour manipuler les bit sur le port
exemple: #define PIN_A1 ((PORTC &_BV(1)) >> 1)
Les # sont des directives pour le pré processus de compilation.
Le #define ne fait que remplacer le texte cité après l'alias , c'est carrément du traitement de texte.

Les #if #else #endif sont des opérateurs de compilation conditionnelle
Cela peut aussi utiliser les #define avec #ifdef etc

Jf
 
  • Réagir
Reactions: Vik'TheBike
V

Vik'TheBike

Nouveau
18 Jan 2024
22
Agonac
Tout à fait, et pour ajouter à ce que dit @speedjf37 , je dirai qu'il est important de ne pas parler de variable lorsqu'il s'agit de #define, ce ne sont pas des variables, mais bien du code (du texte).

On devrait noter:
#define ALIAS valeur

plutôt que
#define VARIABLE valeur
 
  • Réagir
Reactions: wika58
W

wika58

Compagnon
17 Déc 2006
12 756
FR-54560 Lorraine
Donc quand on définit toutes les affectations de pin en debut de programme, l'instruction
#define PinLed 4
est bien la bonne pratique...?
 
F

furynick

Compagnon
29 Jan 2017
1 235
Portet-sur-Garonne
... et non
comme dit plus haut, les #define sont traités par le pré-processeur.
En (très) gros, le processus de compilation se décompose en deux gros traitements :
  1. Le pré-processeur va générer le code source final adapté à la situation
  2. Le compilateur va transformer le code source final en langage machine
Par exemple on a le code suivant (blink test ultra basique)

Le pré-processeur va transformer ça en

En soi ça ne pose aucun problème, mais dans le cas suivant on pourrait avoir un pb :
Le résultat affiché sera 169 et à priori le compilateur ne bronchera pas (c'est peut-être plus le cas aujourd'hui mais ça illustre la problématique) !!

En typant la constante comme ci-après, normalement le compilateur devrait sortir une alerte parce qu'il y a une potentielle incompatibilité de type.

C'est assez vicieux comme erreur et le compilateur peut ne rien voir ou être paramétré pour ne pas être sensible à ce type de problème.
C'est pour cette raison qu'il est fortement conseillé d'utiliser des constantes typées plutôt que des #define.
 
  • Réagir
Reactions: Philippe85
F

furynick

Compagnon
29 Jan 2017
1 235
Portet-sur-Garonne
Hormis les constantes, les #define restent extrêmement utiles pour rendre le code portable (multi-architecture) ou pour limiter les réécritures de code (macro).
 
W

wika58

Compagnon
17 Déc 2006
12 756
FR-54560 Lorraine
Merci d'avoir pris le temps d'expliquer en détail...
Pas sûr de tout comprendre à la première lecture... mais j'en ferai une seconde...
 
G

gégé62

Compagnon
26 Fev 2013
4 222
Harnes (Pas de Calais)
switch case...
ça c'est magique, je l'utilise souvent, dès que le type de programme s'y prête, un truc séquentiel....ça décompose le sketch en différentes situations possibles et ça simplifie beaucoup la lecture, donc le travail....
 
F

fredcoach

Compagnon
11 Jan 2013
1 452
Hautes Alpes
ça c'est magique, je l'utilise souvent, dès que le type de programme s'y prête, un truc séquentiel....ça décompose le sketch en différentes situations possibles et ça simplifie beaucoup la lecture, donc le travail....
Attention, le switch case façon C est dangereux, même si je l'aime beaucoup.
Il y a un petit mot à la fin du case qu'il ne faut pas oublier et dont l'absence n'est pas détectée puisqu'elle est légale.
C'est pourquoi des compilateurs C à très haute sureté interdisent le switch.
 
W

wika58

Compagnon
17 Déc 2006
12 756
FR-54560 Lorraine
Oui ça j'ai vu... le break...

Mais sinon ça a l'air pas mal et dans le cours MOOC ils l'utilisent pour en faire une machine d'état...
 
G

gégé62

Compagnon
26 Fev 2013
4 222
Harnes (Pas de Calais)
oui il ne faut pas oublier les break, mais bon, je ne comprends pas qu'on les interdise. Je suppose qu'on peut obtenir le même résultat avec des if et une sorte de flag qui prend plusieurs valeurs selon les cas, mais déjà dans la plupart des sketches il y a beaucoup de if en général, imbriqués ou non, et je trouve que d'avoir les différentes séquences définies par les "case" du switch permet de mieux les voir. C'est comme si on les encadrait ...
 
F

furynick

Compagnon
29 Jan 2017
1 235
Portet-sur-Garonne
Il ne s'emploie pas tant que ça le switch-case mais c'est clairement très pratique et améliore considérablement la lisibilité pour peu qu'on n'oublie pas le break ... on qu'on utilise son absence à bon escient ce qui peut se révéler extrêmement pratique pour les conditions additives qui seraient ingérables avec de simples if
 
F

fredcoach

Compagnon
11 Jan 2013
1 452
Hautes Alpes
Tout à fait d'accord, j'utilise moi-même assez souvent le switch. Cependant, il est vrai qu'il présente un risque d'erreur et dans certaines applications (aéronautique) c'est déjà trop! Mais je pense qu'on pourrait supprimer ce risque sans être aussi radical.
 
W

wika58

Compagnon
17 Déc 2006
12 756
FR-54560 Lorraine
Oui et on parle tjrs de l'utilisation de l'Arduino dans nos projets DIY pour l'atelier... bien sûr... :rolleyes:
 
C

coredump

Compagnon
8 Jan 2007
5 241
FR-06
Pour ceux qui aiment les switchs:

void
send(short *to, short *from, int count)
{
int n=(count+7)/8;
switch(count%8) {
case 0:
do { *to = *from++;
case 7: *to = *from++;
case 6: *to = *from++;
case 5: *to = *from++;
case 4: *to = *from++;
case 3: *to = *from++;
case 2: *to = *from++;
case 1: *to = *from++;
} while(--n>0);
}
}
 
  • Réagir
Reactions: lion10
F

furynick

Compagnon
29 Jan 2017
1 235
Portet-sur-Garonne
Il picote celui là, une boucle imbriquée dans le switch j'aurais pas tenté.
 

Sujets similaires

W
Réponses
122
Affichages
12 490
Arduino
Philippe85
P
N
Réponses
3
Affichages
935
Arduino
jpbbricole
jpbbricole
lolo
Réponses
0
Affichages
485
lolo
T
Réponses
1
Affichages
324
T
D
Réponses
0
Affichages
270
Siemens
dodochef
D
osiver
Réponses
14
Affichages
40 050
osiver
Dudulle
Général langage MMBASIC
Réponses
8
Affichages
1 201
Dudulle
J
Réponses
12
Affichages
649
R
P
Réponses
33
Affichages
20 215
W
T
Réponses
2
Affichages
29 445
Autres logiciels FAO
Tristan l'apprenti
T
esloch
Réponses
0
Affichages
385
esloch