Поддерживает ли Arduino резьбу?

У меня есть пара задач, связанных с arduino, но одна из них занимает очень много времени, поэтому я подумал об использовании потоков для их одновременного запуска. У меня есть Arduino Mega

[Обновить] Наконец, через четыре года я могу установить FreeRTOS в свой Arduino Mega. Вот ссылка link

Ответы

Ответ 2

Пока нет, но я всегда использую эту библиотеку с большими проектами: https://github.com/ivanseidel/ArduinoThread

Я помещаю обратный вызов в прерывание таймера, и вуаля! У вас есть псевдопотоки, работающие на Arduino...

Ответ 3

Просто, чтобы сделать эту цепочку более полной: есть также protothreads, у которых очень малый объем памяти (пару байтов, если я правильно помню) и сохраняю переменные локальные для потока; очень удобно и экономить время (гораздо меньше конечных автоматов → более читаемый код).

Примеры и код: arduino-class/ProtoThreads wiki

Просто, чтобы вы знали, какие результаты вы можете ожидать: последовательная связь @153K6 обеспечивает скорость передачи данных для потоков: мигание статусных диодов, сохранение времени, оценка запрошенных функций, обработка ввода-вывода и логика и все на atmega328.

Ответ 4

Не настоящая резьба, но TimedActions - хорошая альтернатива для многих применений

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

Конечно, если одна задача блокируется, другие тоже будут, в то время как потоки могут позволить одной задаче заморозить, а остальные будут продолжаться...

Ответ 5

Предыдущий ответ верен, однако, arduino обычно работает довольно быстро, поэтому, если вы правильно используете свой код, он может выполнять задачи более или менее одновременно.

Лучшая практика - сделать свои собственные функции и не помещать слишком много реального кода в цикл void по умолчанию

Ответ 6

Вы можете использовать arduinos

Он предназначен для среды Arduino. Особенности:

  • Только статическое распределение (no malloc/new)
  • Поддержка переключения контекста при задержке выполнения
  • реализует семафоры
  • Легкий, как процессор, так и память

Я использую его, когда мне нужно получать новые команды из bluetooth/network/serial при выполнении старых, а старые имеют задержку в них. Один поток - это поток потока, который выполняет следующий цикл:

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
}

Другой - это командный поток, который выполняет команду:

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

Ответ 8

Arduino не поддерживает многопоточное программирование.

Однако были некоторые обходные пути, например, в этом проекте (вы можете установить его также из Arduino IDE).

Кажется, вам нужно самим определять время расписания, тогда как в реальной многопоточной среде именно ОС решает, когда выполнять задачи.

В качестве альтернативы вы можете использовать protothreads

Ответ 9

Arduino не поддерживает многопоточность. Однако вы можете сделать следующую лучшую вещь и структурировать свой код вокруг конечных автоматов, работающих в режиме чередования.

Хотя существует множество способов реализовать ваши задачи в качестве конечных автоматов, я рекомендую эту библиотеку (https://github.com/Elidio/StateMachine). Эта библиотека абстрагирует большую часть процесса.

Вы можете создать конечный автомат как класс:

#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);
      }
};

Макрос STATEMACHINE() абстрагирует наследование классов, макрос CREATE_STATE() абстрагирует создание оболочки состояния, макрос INIT_STATE() абстрагирует перенос метода, а макрос STATE() абстрагирует ссылку на оболочку состояния в классе конечного автомата.

Переход между состояниями абстрагируется оператором << между классом конечного автомата и состоянием, и если вам нужен переход с отложенным состоянием, все, что вам нужно сделать, это использовать этот оператор с целым числом, где целое число - это задержка в миллисекундах.

Чтобы использовать конечный автомат, сначала вы должны создать его экземпляр. Объявление ссылки на класс в глобальном пространстве при создании экземпляра его с помощью new в функции настройки может помочь.

Blink *led1, *led2, *led3;


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

Затем вы запускаете состояния в цикле.

void loop() {
    (*led2)();
    (*led1)();
    (*led3)();
}