У меня есть Arduino (duemilanove), подключенная к дисководу для гибких дисков, и я могу с удовольствием управлять шаговым двигателем, используя три контакта на ленточном кабеле к трем цифровым контактам моего Arduino (ну, 2 + земля!).
Я хотел бы управлять несколькими двигателями одновременно, но использование одного Arduino на двигатель будет дорогостоящим. Я немного читал о 555 таймерах. Если бы я хотел управлять двумя двигателями одновременно, независимо друг от друга, с моего единственного Arduino, можно ли было бы это сделать с помощью микросхемы таймера 555 для каждого двигателя?
Arduino является «однопоточным», поэтому я думаю, мне нужен способ передать «команды» (сигналы) для управления шаговыми двигателями на другой чип. Таким образом, один поток Arduino может зацикливаться на каждом чипе, раздавая команды для подключенного к нему двигателя (или, может быть, метод очередности?).
Я также немного читал о прерываниях на Arduino, но я не думаю, что они будут полезны, не так ли?
Это можно сделать с помощью прерываний. Прикрепите прерывание к таймеру, чтобы он срабатывал регулярно (скажем, раз в миллисекунду), и используйте это прерывание, чтобы вывести следующую команду из верхней части очереди (может быть просто массивом).
Затем ваш основной цикл просто добавляет команды в этот массив.
Один 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(). Чтобы изменить скорость шагов, измените это значение.
При условии, что вы будете использовать 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
Оптимальный циник
Олин Латроп