Executer en parallèle

Bonjour,
Mon projet de simulateur consiste a piloter des lampes, des lampes clignotantes, des afficheurs 7 segments, des ecran lcd, des servos moteurs, des stepper, des envoies de caractères, des receptions de caractères, des potentiomètres, bref tout en tas de composants.
Si tout marche bien malheureusement tout fonctionne séquentiellement, ce qui est facheux.
Il y a des boucles (for, while). Je n'utilise aucun delay() mais des delaywithmillis().
Comment pourrais-je faire de tel sorte pour que tout fonctionne en pseudo paralléle (sachant que je n'ai pas d'OS comme sur rasperry ou stm32) ?
Merci d'avance pour vos conseils.

Utilise une bibliothèque qui permet de mettre en oeuvre une machine à états. J-M-L a fait un tuto sur le sujet, si tu veux en savoir plus (pub gratuite ;)). Il existe aussi un tuto en anglais sur le forum qui explique comment faire du "pseudo parallèle" avec un Arduino. Enfin un autre tuto de chez Adafruit.

Quand tu auras lu tout ça, tu seras incollable sur le sujet !!

Ok merci Lesept je vais lire attentivement ces docs :wink:

Bonjour

Cette bibliothèque est spécifiquement conçue pour ce genre d'usage.

Je ne l'ai pas encore adapatée aux ESP, mais sur arduino classique elle fonctionne à merveille.

sinon, cette bibliotheque aussi est faite pour cela :wink: et devrait aussi fonctionner sur ESP

Bonjour,
ce qui m’inquiète un peu c'est les écrans lcd, si c'est rafraîchi fréquemment ça risque de coincer au niveau de la vitesse du processeur : est-ce que ça fonctionne correctement sans ces écrans ?

il suffit d'executer ce qui gère les écrans moins souvent. Ne serait-ce que pour l'aspect de l'affichage, c'est indispensable de toutes manières, sinon ça clignote

Merci à ceux qui m'ont répondu.

J'ai parcouru avec intêret les différents posts, j'avoue être perdu par les différentes solutions et par la complexité de leur mise en oeuvre, étant quelque peu novice en programmation C. :frowning:
L'écran LCD reste une option.
Ma priorité reste l'usage en parallèle des servos et steppers, de allumage des lampes et l'envoie et la réception de caractères vers et depuis le PC depuis un potentiomètre.

Les quelques while() et for() qui restent sont en fait la source des attentes de mes programmes.

tant que lecture de caractères :
Si A faire fonctionner stepper
while() faire deplacer le stepper
Si B faire fonctionner stepper
while() faire deplacer le stepper
Si C faire fonctionner servo
while() faire deplacer le servo
Si D faire fonctionner servo
while() faire deplacer le servo
Si E faire fonctionner servo
while() faire deplacer le servo

si pression bouton a, allumage lampes
si pression bouton a, allumage afficheur 7 seg
si potar tourné, envoie de caractères vers PC

Les boucles while et for sont faciles à remplacer par des if dans une organisation en machine(s) à états.

As-tu lu le tuto de J-M-L sur les machines à états dont le lien a été donné en #1 ?

Si tu veux, poste ton programme actuel et je te montre comment adapter ça avec la librairie YASM.

Une question : si c'est un projet étudiant, est-il sage de se reposer sur une bibliothèque qui fait tout le boulot ?

bah la bibli ne fait pas tout le boulot, ça le simplifie, et souvent ça évite des erreurs. Mais la logique reste la même.

lesept:
Une question : si c'est un projet étudiant, est-il sage de se reposer sur une bibliothèque qui fait tout le boulot ?

Hello, ce n'est pas un projet étudiant (l'étudiant a quitté les bancs de son école d'ingé en 92!), c'est un projet personnel de simulateur.
et oui: Les boucles while et for sont faciles à remplacer par des if dans une organisation en machine(s) à états. => c'est exactement ce que je cherche a faire.
Je vais potasser la lib yasm, actuellement mes fichiers .ino, .h et .ccp sont relativement longs (et surement pas optimisés) :wink:
mes boucles while() et for() ne sont pas basées sur du timing mais sur des évènements.
ex:
tant que l'indicateur de vitesse n'est pas a 100, ou tant que je n'ai pas envoyé 50 caractères, tout le reste du code (servos et autres stepper, afficheurs) attendent.
la fonction stepper() n'est elle pas une fonction bloquante comme delay() ?

peu importe que les programmes ne soient pas optimisés, il n'y a pas de honte à avoir

si ils sont longs il suffit de les joindre au message en fichiers attachés

N'y a t'il pas des exemples sur lesquels je peux m'inspirer, car je me vois mal fournir l'ensemble des ino, .h et .cpp developpés depuis 2,5 ans ainsi ...?

plusieurs .ino ? pourtant tu ne peux pas en utiliser plusieurs en même temps sur la même carte, donc je ne comprends pas bien…

des exemples… si plein. regardes dans “réalisations et projets finis” tous les projets qui utilisent des machines à états

mettons que tu aies le code suivant, pour faire clignoter une led :

const byte pinLed1 = 13;

void setup()
{
  pinMode(pinLed1, OUTPUT);
}

void loop()
{
  digitalWrite(pinLed1, HIGH);
  delay(500);
  digitalWrite(pinLed1, LOW);
  delay(500);
}

et le code suivant, qui allume une led tant qu’on ne mesure pas une tension proche de 5V sur l’entrée analogique A0, puis l’éteint pendant 10s :

const byte pinLed2 = 13;
const byte pinEntree = A0;

void setup()
{
  pinMode(pinLed2, OUTPUT);
}

void loop()
{
  while(analogRead(pinEntree) < 1000)
  {
    digitalWrite(ledPin2, HIGH);
  }

  digitalWrite(ledPin2, LOW);
  delay(10000);
}

ces deux codes sont bloquants, il y a des delay(), un while(), si on les combine directement ça ne fera absolument pas ce que l’on voudrait

mais pour combiner ces deux codes de manière non-bloquante avec la librairie YASM, on peut faire :

#include <yasm.h>

const byte pinLed1 = 12;
const byte pinLed2 = 13;
const byte pinEntree = A0;

YASM exempleDeWhile;
YASM autreTache;

void setup()
{
  pinMode(pinLed1, OUTPUT);
  pinMode(pinLed2, OUTPUT);

  exempleDeWhile.next(intoTheWhile); //on donne aux tâches leur état initial
  autreTache.next(ledON);
}

void loop()
{
  exempleDeWhile.run(); //on execute les tâches
  autreTache.run();
}


////////fonctions correspondant à la tâche "exempleDeWhile" //////////

void intoTheWhile()
{
  if ( analogRead(pinEntree) > 1000 )
  {
    exempleDeWhile.next(apresLeWhile);
    return;
  }

  /*ici on fait ce que l'on ferait dans un :
    while(analogRead(pinEntree) < 1000)
    {
      digitalWrite(pinLed, HIGH);
    }
  */
  digitalWrite(pinLed2, HIGH);

}

void apresLeWhile()
{
  //ici ont fait ce qui serait fait après le } du while
  digitalWrite(pinLed2, LOW);

  if( exempleDeWhile.elapsed(10000))
    exempleDeWhile.next(intoTheWhile);
}



//////////fonctions correspondant à la tâche "autreTache" ///////////

void ledON()
{
  digitalWrite(pinLed1, HIGH);

  if (autreTache.elapsed(500))
    autreTache.next(ledOFF);
}

void ledOFF()
{
  digitalWrite(pinLed1, LOW);

  if (autreTache.elapsed(500))
    autreTache.next(ledON);
}

Merci pour ton aide Bricofoy, je vais regarder de plus près ton exemple. il y a plusieurs ino car j’ai plusieurs cartes qui communiquent entre elles.

Après ce n'est qu'un exemple vite fait. Je ne l'ai pas testé, il est possible que j'ai oublié un ; qqpart.

Ce serait sans doute plus parlant pour toi de faire la même chose à partir d'un de tes .ino, si tu veux en poster un.

Ça communique comment entre les cartes ? liaison série ?

J'ai 3 cartes arduino, qui communiquent entre elles par liaison serie, une possède le code maitre, les autres se contentent de gérer les loupiottes, servos et stepper, les fonctions actives sont gérées par leur propre .h et .cpp (plus facile a maintenir).
Individuellement les fonctions marchent, mais une fois que tout prend vie, ça ne me plait pas, ça rame.
En 2 ans je me suis remis au cablage, a l'electronique, à l'arduino et a la programmation C
Plus d'info sur : Redirecting...

ha vu ton pseudo je me doutais que c'était pour du ferroviaire :slight_smile: Je te suis déjà sur FB

c'est peut-être la liaison série qui fait ramer.

Mais il me faudrait vraiment un exemple du code réel

si il n'y a que 3 cartes c'est pas non plus des montagnes de fichiers. ce sont des cartes arduino ou des stm32 ?

peut-être que le plus simple serait d'utiliser github ?