основной вопрос ардуино - нужен ли мне таймер 555?

У меня есть Arduino (duemilanove), подключенная к дисководу для гибких дисков, и я могу с удовольствием управлять шаговым двигателем, используя три контакта на ленточном кабеле к трем цифровым контактам моего Arduino (ну, 2 + земля!).

Я хотел бы управлять несколькими двигателями одновременно, но использование одного Arduino на двигатель будет дорогостоящим. Я немного читал о 555 таймерах. Если бы я хотел управлять двумя двигателями одновременно, независимо друг от друга, с моего единственного Arduino, можно ли было бы это сделать с помощью микросхемы таймера 555 для каждого двигателя?

Arduino является «однопоточным», поэтому я думаю, мне нужен способ передать «команды» (сигналы) для управления шаговыми двигателями на другой чип. Таким образом, один поток Arduino может зацикливаться на каждом чипе, раздавая команды для подключенного к нему двигателя (или, может быть, метод очередности?).

Я также немного читал о прерываниях на Arduino, но я не думаю, что они будут полезны, не так ли?

Я возражаю против этого вопроса по причине избыточности — ответ на вопрос «нужен ли мне таймер 555» всегда положительный. Это не обязательно должно быть связано, но без него вы будете испытывать симптомы грусти, скуки и тревожного ноющего чувства, что вы что-то забыли.
Неправильный! Ответ на вопрос « Нужен ли мне таймер 555 » всегда «НЕТ». Таймеры 555 — это старые грубые аналоговые детали, которые занимают много места, энергии и требуют, чтобы аналоговые детали в лучшем случае выполняли неаккуратную синхронизацию. Им действительно нет оправдания в новых конструкциях с позднего плейстоцена. Единственная оставшаяся ниша — невежественные любители и прочие любители.

Ответы (4)

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

Затем ваш основной цикл просто добавляет команды в этот массив.

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

Существуют специальные микросхемы драйверов шаговых двигателей, которые намного лучше и проще, чем использование таймера 555. Дисковод будет использовать один (возможно, встроенный в другой чип). Обычно они принимают простые сигналы шага вверх/вниз и преобразуют их в правильную последовательность импульсов.

Редактировать

Пример кода с использованием библиотеки Timer1 :

#include <TimerOne.h>

void test()
{
  digitalWrite(5,HIGH);
  delayMicroseconds(100);
  digitalWrite(5,LOW);
}

void setup()
{
  Timer1.attachInterrupt(&test,100000);
}

void loop()
{
}

Это приведет к тому, что цифровой контакт 5 станет высоким, а затем низким каждые 100 000 мкс - вы видите, что в основном цикле вообще ничего нет. Просто замените два вызова digitalWrite() кодом для однократного переключения двигателей . Вам не нужно указывать какую-либо задержку между шагами в этой части кода - эта задержка устанавливается значением 100000 в функции Timer1.attachInterrupt(). Чтобы изменить скорость шагов, измените это значение.

Привет Majenko, спасибо за ваш ответ! Если я хочу управлять двумя двигателями отдельно, хотя я не понимаю, как это будет работать? Управление одним двигателем использует основной цикл Arduino. Для шага каждые 1 мс для двигателя 1 основной цикл выполняет «шаг, задержка 1, шаг, задержка 1», поэтому он «занят». Даже с прерываниями, как я могу независимо управлять другим двигателем с задержкой в ​​​​2 мс, например «шаг, задержка 2, шаг, задержка 2» и т. Д.
Должен ли я запускать прерывания еще быстрее и делать что-то вроде «шаговый двигатель 1, шаговый двигатель 2, задержка $in_microseconds», чтобы я переключал свой основной цикл между двумя двигателями?
У вас не было бы задержки в прерывании. Задержка вызвана таймером. У вас будет просто «шаг 1; шаг 2» в прерывании. Затем это будет вызываться каждые 1 мс, поэтому оба двигателя будут делать шаг один раз в миллисекунду.
Взгляните на arduino.cc/playground/Code/Timer1 .
Просто чтобы объяснить немного больше, вы можете запускать процедуру обслуживания для прерывания таймера каждую миллисекунду, в процедуре обслуживания шаг каждого двигателя, который желательно иметь шаг. Через миллисекунду вы снова наступаете на них. Вы можете сделать это, имея переменную «желаемого положения» для каждого двигателя, и процедура обслуживания будет сравнивать ее с «текущей позицией», чтобы решить, нужно ли ей делать шаг, если да, она выдает шаг вверх или вниз и увеличивает / уменьшает переменную положения. Убедитесь, что все переменные, используемые как ISR, так и основным потоком, объявлены как «изменчивые». В конце концов, нарастите скорость.
Спасибо, Маженко, за отличный совет и разъяснение. Это именно то, что мне нужно, теперь все работает :)

При условии, что вы будете использовать 2 выходных контакта на двигатель, вы можете контролировать до ( (контактов GPIO) / 2 ), используя простой программный механизм, называемый планировщиком.

Если вы новичок, я предлагаю попробовать реализовать совместный планировщик, это, вероятно, проще всего. Если у вас с этим проблемы, вам следует обратиться за помощью к этой книге . Это очень хорошая, очень полная бесплатная книга под названием «Шаблоны для встраиваемых систем, запускаемых по времени». Он хорошо написан и содержит отличную информацию от основ до довольно продвинутых вещей.

Хорошее знание языка C, если это рекомендуется, но если у вас есть проблемы с подобными «указателями функций» или чем-то подобным, не сдавайтесь — посмотрите несколько руководств, как только вы поймете дрейф, это действительно очень просто :)

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

Вы можете управлять примерно 6 низковольтными двигателями до 5 В, используя этот код, и вы можете настроить время для каждого из них, изменив код, или вы можете использовать светодиод в качестве выхода для подачи сигнала на 6 других реле для любого времени, которое вы хотите. Для более высокой мощности вам может понадобиться еще один источник питания, это довольно просто сделать таким образом, надеюсь, это сработает для вас.

/*
  Switch statement  with serial input

 Demonstrates the use of a switch statement.  The switch
 statement allows you to choose from among a set of discrete values
 of a variable.  It's like a series of if statements.

 To see this sketch in action, open the Serial monitor and send any character.
 The characters a, b, c, d, and e, will turn on LEDs.  Any other character will turn
 the LEDs off.

 The circuit:
 * 5 LEDs attached to digital pins 2 through 6 through 220-ohm resistors

 created 1 Jul 2009
 by Tom Igoe 

This example code is in the public domain.

 http://www.arduino.cc/en/Tutorial/SwitchCase2
 */

void setup() {
  // initialize serial communication:
  Serial.begin(9600); 
   // initialize the LED pins:
      for (int thisPin = 2; thisPin < 7; thisPin++) {
        pinMode(thisPin, OUTPUT);
      } 
}

void loop() {
  // read the sensor:
  if (Serial.available() > 0) {
    int inByte = Serial.read();
    // do something different depending on the character received.  
    // The switch statement expects single number values for each case;
    // in this exmaple, though, you're using single quotes to tell
    // the controller to get the ASCII value for the character.  For 
    // example 'a' = 97, 'b' = 98, and so forth:

    switch (inByte) {
    case 'a':    
      digitalWrite(2, HIGH);
      break;
    case 'b':    
      digitalWrite(3, HIGH);
      break;
    case 'c':    
      digitalWrite(4, HIGH);
      break;
    case 'd':    
      digitalWrite(5, HIGH);
      break;
    case 'e':    
      digitalWrite(6, HIGH);
      break;
    default:
      // turn all the LEDs off:
      for (int thisPin = 2; thisPin < 7; thisPin++) {
        digitalWrite(thisPin, LOW);
      }
    } 
  }
}

В зависимости от того, что еще вы планируете делать с микроконтроллером, одной из альтернатив может быть замена Arduino несколькими микросхемами ATTiny85. Они стоят около 2,50 долларов США каждый и могут быть запрограммированы через Arduino с помощью его IDE. Инструкции см. по следующим URL-адресам.
http://hlt.media.mit.edu/?p=1229
http://www.youtube.com/watch?v=30rPt802n1k

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