web-dev-qa-db-fra.com

Arduino prend-il en charge le threading?

J'ai quelques tâches à faire avec arduino, mais l'une d'elles prend très longtemps, alors je pensais utiliser des threads pour les exécuter simultanément ... J'ai un Arduino Mega

[Mise à jour] Enfin, après quatre ans, je peux installer FreeRTOS dans mon méga Arduino. Voici un link

17
Snake Sanders
13
Filipe YaBa Polido

Pas encore, mais j'utilise toujours cette bibliothèque avec de gros projets: https://github.com/ivanseidel/ArduinoThread

Je place le rappel dans une interruption de minuterie, et voilá! Vous avez des pseudo-threads en cours d'exécution sur l'Arduino ...

5
Ivan Seidel

Juste pour rendre ce fil plus complet: il y a aussi protothreads qui ont une très petite empreinte mémoire (quelques octets si je me souviens bien) et conserve les variables locales à thread; très pratique et gain de temps (beaucoup moins de machines à états finis -> code plus lisible).

Exemples et code: arduino-class/ProtoThreads wiki

Pour que vous sachiez quels résultats vous attendez: communication série @ 153K6 en bauds avec threads pour: diodes d'état clignotantes, indication de l'heure, évaluation des fonctions demandées, traitement et logique IO, etc. 

5
Mr. Girgitt

Pas de réel threading mais TimedActions est une bonne alternative pour de nombreuses utilisations

http://playground.arduino.cc/Code/TimedAction#Example

Bien sûr, si une tâche est bloquante, les autres aussi, tandis que les threads peuvent laisser une tâche se figer et les autres continueront ...

4
FrancescoMM

Arduino ne prend pas en charge la programmation multithread. 

Cependant, il y a eu des solutions de contournement, par exemple celle de ce projet (vous pouvez également l'installer à partir de l'IDE Arduino). 

Il semble que vous deviez définir vous-même le temps de planification, tandis que dans un véritable environnement multithread, c'est le système d'exploitation qui décide quand exécuter des tâches. 

Sinon, vous pouvez utiliser protothreads

1
Francesco Boi

Vous pouvez utiliser arduinos

Il est conçu pour l'environnement Arduino. Caractéristiques:

  • Allocation statique uniquement (pas de malloc/nouveau)
  • Prise en charge du changement de contexte lors du retard d'exécution
  • Implémente des sémaphores
  • Léger, cpu et mémoire

Je l'utilise quand j'ai besoin de recevoir de nouvelles commandes de bluetooth/réseau/série tout en exécutant les anciennes et que les anciennes ont un délai .. .. Un.

while (1) {
    while ((n = Serial.read()) != -1) {
        // do something with n, like filling a buffer
        if (command_was_received) {
            arduinos_create(command_func, arg);
        }
    }
    arduinos_yield(); // context switch to other threads
}

L'autre est le fil de commande qui exécute la commande:

int command_func(void* arg) {
    // move some servos
    arduinos_delay(1000); // wait for them to move
    // move some more servos
}
1
eyal

La réponse précédente est correcte, cependant, l'arduino fonctionne généralement assez rapidement, donc si vous chronométrez correctement votre code, il peut accomplir des tâches plus ou moins simultanément.

La meilleure pratique consiste à créer vos propres fonctions et à éviter de mettre trop de code réel dans la boucle vide par défaut.

1
lkrasner

Non, vous ne pouvez pas, mais vous pouvez utiliser la minuterie.

1
Oshi_007

Arduino ne supporte pas les threads. Cependant, vous pouvez faire de même et structurer votre code en fonction des machines à états qui fonctionnent en entrelacement.

Bien qu'il y ait beaucoup de façons d'implémenter vos tâches en tant que machines d'état, je recommande cette bibliothèque ( https://github.com/Elidio/StateMachine ). Cette bibliothèque résume l'essentiel du processus.

Vous pouvez créer une machine à états en tant que classe comme ceci:

#include "StateMachine.h"
class STATEMACHINE(Blink) {
  private:
    int port;
    int waitTime;
    CREATE_STATE(low);
    CREATE_STATE(high);

    void low() {
      digitalWrite(port, LOW);
      *this << &STATE(high)<< waitTime;
    }
    void high() {
      digitalWrite(port, HIGH);
      *this << &STATE(low)<< waitTime;
    }
  public:
    Blink(int port = 0, int waitTime = 0) :
      port(port),
      waitTime(waitTime),
      INIT_STATE(low),
      INIT_STATE(high)
      {
        pinMode(port, OUTPUT);
        *this << &STATE(low);
      }
};

La macro STATEMACHINE() résume les héritages de classe, la macro CREATE_STATE() résume la création de l’enveloppe d’état, la macro INIT_STATE() présente une méthode abstraite et la référence de la macro STATE() résume l’état dans la classe de machine à états.

La transition d'état est résumée par l'opérateur << entre la classe de machine à états et l'état, et si vous souhaitez une transition d'état retardée, il vous suffit d'utiliser cet opérateur avec un entier, où l'entier est le délai en millisecondes.

Pour utiliser la machine à états, vous devez d'abord l'instancier. Déclarer une référence à la classe dans l'espace global tout en l'instanciant avec new sur la fonction de configuration pourrait faire l'affaire

Blink *led1, *led2, *led3;


void setup() {
  led1 = new Blink(12, 300);
  led2 = new Blink(11, 500);
  led3 = new Blink(10, 700);
}

Ensuite, vous exécutez les états sur la boucle. 

void loop() {
    (*led2)();
    (*led1)();
    (*led3)();
}
0
Luiz Menezes