roboforum.ruТехнический форум по робототехнике. |
|
|
/*
ServoStepper
Управление шаговым двигателем
*/
// ISR pinchangeint interrupt service routine
#include <C:\Work\arduino-1.5.2\libraries\PinChangeInt\PinChangeInt.h>
unsigned int latency ;
unsigned int latencySum ;
unsigned int sampleCount ;
unsigned char timerLoadValue;
// volatile int TestPerem; //Буду инкрементить в обработчике
// volatile int dir; //Направление вращения двигателя
#define Dir_X_pin 5 // Пин направления X
#define Dir_Y_pin 6 // Пин направления Y
#define Dir_Z_pin 7 // Пин направления Z
#define motor_X_pin_1 10
#define motor_X_pin_2 11
#define motor_X_pin_3 12
#define motor_X_pin_4 13
#define motor_Y_pin_1 A0
#define motor_Y_pin_2 A1
#define motor_Y_pin_3 A2
#define motor_Y_pin_4 A3
#define motor_Z_pin_1 8
#define motor_Z_pin_2 9
#define motor_Z_pin_3 A4
#define motor_Z_pin_4 A5
volatile long StepXcounter; //Шаги по X
volatile long StepYcounter; //Шаги по Y
volatile long StepZcounter; //Шаги по Z
byte locateStat; //Статус сигнал (1-есть)
volatile byte locateSensor; //Для хранения считанного
//unsigned int locatecount; //счетчик количества принятых одинаковых состояний
//Массив для моторов
int MotorPins[] = {motor_X_pin_1, motor_X_pin_2, motor_X_pin_3, motor_X_pin_4, motor_Y_pin_1, motor_Y_pin_2, motor_Y_pin_3, motor_Y_pin_4, motor_Z_pin_1, motor_Z_pin_2, motor_Z_pin_3, motor_Z_pin_4 };
//шаги для моторов
volatile byte curstep[]= {0, 0, 0}; //текущий шаг
//uint8_t latest_interrupted_pin; //для PinChangeInt
//uint8_t interrupt_count[20]={0}; // 20 possible arduino pins //для PinChangeInt
//void quicfunc() {
// latest_interrupted_pin=PCintPort::arduinoPin;
// interrupt_count[latest_interrupted_pin]++;
//}
void setup() {
//Запускает последовательный порт
//Serial.begin(9600);
Serial.begin(115200);
StepXcounter=0; //Сбросим счетчик шагов X
pinMode(motor_X_pin_1, OUTPUT);
pinMode(motor_X_pin_2, OUTPUT);
pinMode(motor_X_pin_3, OUTPUT);
pinMode(motor_X_pin_4, OUTPUT);
pinMode(motor_Y_pin_1, OUTPUT);
pinMode(motor_Y_pin_2, OUTPUT);
pinMode(motor_Y_pin_3, OUTPUT);
pinMode(motor_Y_pin_4, OUTPUT);
pinMode(motor_Z_pin_1, OUTPUT);
pinMode(motor_Z_pin_2, OUTPUT);
pinMode(motor_Z_pin_3, OUTPUT);
pinMode(motor_Z_pin_4, OUTPUT);
Serial.println("Motor setup end");
Serial.println(motor_Y_pin_1);
Serial.println(motor_Y_pin_2);
// locateStat=0;
// TestPerem=locateStat;
// initialize the digital pin as an output.
// Pin 13 has an LED connected on most Arduino boards:
//pinMode(13, OUTPUT);
pinMode(Dir_X_pin, INPUT); digitalWrite(Dir_X_pin, LOW); //Пин для направления по оси Х
pinMode(Dir_Y_pin, INPUT); digitalWrite(Dir_Y_pin, LOW); //Пин для направления по оси Y
pinMode(Dir_Z_pin, INPUT); digitalWrite(Dir_Z_pin, LOW); //Пин для направления по оси Z
//pinMode(LOC_POWER,OUTPUT);
//pinMode(LOC_INPUT,INPUT);
//digitalWrite(LOC_POWER, HIGH);
pinMode(2, INPUT); digitalWrite(2, LOW);
attachInterrupt(0, Step_X_int, RISING); // Разрешить прерывание по изменению состояния вывода 2
pinMode(3, INPUT); digitalWrite(3, LOW);
attachInterrupt(1, Step_Y_int, RISING); // Разрешить прерывание по изменению состояния вывода 3
pinMode(4, INPUT); digitalWrite(4, LOW);
PCintPort::attachInterrupt(4, Step_Z_int, RISING); // Разрешить прерывание по изменению состояния вывода 4
interrupts(); // Разрешить прерывания глобально
Serial.println("---------------------------------------");
//Сообщение о запуске программы
Serial.println("Timer2 Test");
//Запускает таймер и получает загружаемое значение таймера.
timerLoadValue=SetupTimer2(10);
//Выводит загружаемое значение таймера
Serial.print("Timer2 Load:");
Serial.println(timerLoadValue,HEX);
}
void loop() {
// digitalWrite(13, HIGH); // set the LED on
delay(10); // wait
// digitalWrite(13, LOW); // set the LED off
sampleCount++;
//Как только наберется 10 замеров, вычисляет и выводит результат измерений
if(sampleCount>100) {
//обнуляет значения сумм
sampleCount=0;
latencySum=0;
//Выводит инфо
Serial.println("count:");
Serial.print(" Int_X=");
Serial.println (StepXcounter);
Serial.print(" Int_Y=");
Serial.println (StepYcounter);
Serial.print(" Int_Z=");
Serial.println (StepZcounter);
Serial.print(" curstep[0]=");
Serial.println (curstep[0]);
// Serial.println(latest_interrupted_pin);
}
}
void Step_X_int()
{
// digitalWrite(13, HIGH);
if (digitalRead(Dir_X_pin))
{StepXcounter++;
stepMotor(0 ,1);}
else
{StepXcounter--;
stepMotor(0 ,0);}
// Serial.print(" Int_X=");
// Serial.println (StepXcounter);
}
void Step_Y_int()
{
// digitalWrite(13, HIGH);
if (digitalRead(Dir_Y_pin))
{StepYcounter--;
stepMotor(1 ,1);}
else
{StepYcounter++;
stepMotor(1 ,0);}
// Serial.println(" Int_Y");
}
void Step_Z_int()
{
// latest_interrupted_pin=PCintPort::arduinoPin;
// interrupt_count[latest_interrupted_pin]++;
// digitalWrite(13, HIGH);
if (digitalRead(Dir_Z_pin))
{StepZcounter--;
stepMotor(2 ,1);}
else
{StepZcounter++;
stepMotor(2 ,0);}
// Serial.println(" Int_Z");
}
//Timer2 указатель вектора прерывания по переполнению
ISR(TIMER2_OVF_vect) {
//Проверим направление, если больше границ - поменяем на противоположное
// if (curstep> 6000 || curstep<0){dir=-dir;}
// curstep+=dir;
// stepMotor(curstep);
//Захват текущего значения таймера. Это величина ошибки
//из-за задержки обработки прерывания и работы этой функции
int latency=TCNT2;
//Перезагрузка таймера и коррекция по задержке
//TCNT2=latency+timerLoadValue;
TCNT2=timerLoadValue;
}
long SetupTimer2(long Frequency){
#define TIMER_CLOCK_FREQ 15625.0 //УКАЗЫВАЕМ ПОСЛЕ делителя. Имеено ПОСЛЕ
//#define TIMER_CLOCK_TICK 2000000.0
//2MHz for /8 prescale from 16MHz
//Установка Таймера2.
//Конфигурирует 8-битный Таймер2 ATMega168 для выработки прерывания
//с заданной частотой.
//Возвращает количество тиков таймера на один период требуемой частоты
int CountPer=((257.0-(TIMER_CLOCK_FREQ / (long)Frequency))+0.5);
//Установки Таймер2: режим 0
TCCR2A = 0;
//Частота = 16MHz/1024 = 15625 герц или 64 мкс
//Делитель /1024 дает нам хороший рабочий диапазон
//так что сейчас мы просто жестко запрограммируем это.
//в битах CS22 (2), CS21 (1), CS20 (0) регистра TCCR2B которые устанавливают режим тактирования.
// •000 - таймер остановлен
// •001 - CLK
// •010 - CLK/8
// •011 - CLK/32
// •100 - CLK/64
// •101 - CLK/128
// •110 - CLK/256
// •111 - CLK/1024
TCCR2B = 1<<CS22 | 1<<CS21 | 1<<CS20; //это на 8
//Подключение прерывания по переполнению Timer2
TIMSK2 = 1<<TOIE2;
//загружает таймер для первого цикла (если меньше 255, или
//TCNT2=0;
return(CountPer);
}
void stepMotor(int Motor, int Step) //Motor - от 0 до 2 номер мотора Step 0 или +1
{
//Serial.println(curstep[Motor]);
int i; //Сдвиг для номеров пинов мотора
if (Step)
{
// Serial.println("StepMotor Step=1");
if (curstep[Motor]==7)
{curstep[Motor]=0;}
else
{curstep[Motor]++;}
}
else
{
// Serial.println("StepMotor Step=0");
if (curstep[Motor]==0)
{curstep[Motor]=7;}
else
{curstep[Motor]--;}
}
i=Motor*4; //Сдвиг пинов в массиве MotorPins[]
//Serial.println(curstep[Motor]);
switch (curstep[Motor]) {
case 0: // 1000
// digitalWrite(MotorPins[1], HIGH);
digitalWrite(MotorPins[i+1], LOW);
// digitalWrite(MotorPins[i+2], LOW);
digitalWrite(MotorPins[i+3], LOW);
break;
case 1: // 1100
digitalWrite(MotorPins[i], HIGH);
digitalWrite(MotorPins[i+1], HIGH);
// digitalWrite(MotorPins[i+2], LOW);
// digitalWrite(MotorPins[i+3], LOW);
break;
case 2: // 0100
digitalWrite(MotorPins[i], LOW);
// digitalWrite(MotorPins[i+1], HIGH);
digitalWrite(MotorPins[i+2], LOW);
// digitalWrite(MotorPins[i+3], LOW);
break;
case 3: // 0110
// digitalWrite(MotorPins[i], LOW);
digitalWrite(MotorPins[i+1], HIGH);
digitalWrite(MotorPins[i+2], HIGH);
// digitalWrite(MotorPins[i+3], LOW);
break;
case 4: // 0010
// digitalWrite(MotorPins[i], LOW);
digitalWrite(MotorPins[i+1], LOW);
// digitalWrite(MotorPins[i+2], HIGH);
digitalWrite(MotorPins[i+3], LOW);
break;
case 5: // 0011
// digitalWrite(MotorPins[i], LOW);
// digitalWrite(MotorPins[i+1], LOW);
digitalWrite(MotorPins[i+2], HIGH);
digitalWrite(MotorPins[i+3], HIGH);
break;
case 6: // 0001
digitalWrite(MotorPins[i], LOW);
// digitalWrite(MotorPins[i+1], LOW);
digitalWrite(MotorPins[i+2], LOW);
// digitalWrite(MotorPins[i+3], HIGH);
break;
case 7: // 1001
digitalWrite(MotorPins[i], HIGH);
// digitalWrite(MotorPins[i+1], LOW);
// digitalWrite(MotorPins[i+2], LOW);
digitalWrite(MotorPins[i+3], HIGH);
break;
}
}
void stepMotor1(int dir, int step) //dir - направление step -сколько шагов
//Motor1EN - вывод EN 1 драйвера
//Motor1dir - направление первого
//Motor1step - шаг первого
{
digitalWrite(Motor1EN, LOW);
if (dir)
{
digitalWrite(Motor1dir, HIGH);}
else
{ digitalWrite(Motor1dir, LOW);}
digitalWrite(Motor1step, LOW);
for (int i=0;i<step; i++)
{
delay(200);
digitalWrite(Motor1step, HIGH);
delay(200);
digitalWrite(Motor1step, LOW);
}
delay(200); //чтобы успел шагнуть до выключения
digitalWrite(Motor1EN, HIGH);
}
int Motor1EN = 10;
int Motor1dir = 12;
int Motor1step = 9;
void setup ()
{
pinMode(Motor1EN, OUTPUT);
pinMode(Motor1dir, OUTPUT);
pinMode(Motor1step, OUTPUT);
}
void loop ()
{
digitalWrite(Motor1EN, LOW);
if (dir)
{
digitalWrite(Motor1dir, HIGH);}
else
{ digitalWrite(Motor1dir, LOW);}
digitalWrite(Motor1step, LOW);
for (int i=0;i<step; i++)
{
delay(200);
digitalWrite(Motor1step, HIGH);
delay(200);
digitalWrite(Motor1step, LOW);
}
delay(200);
digitalWrite(Motor1EN, HIGH);
}
for (int i=0;i<step; i++)
stepMotor1(1, 240)
stepMotor1(0, 50)
sketch_oct31a.ino: In function 'void loop()':
sketch_oct31a:16: error: 'dir' was not declared in this scope
sketch_oct31a:18: error: 'stepMotor1' was not declared in this scope
sketch_oct31a:24: error: 'step' was not declared in this scope
я бы сказал, но так как ты лентяй, не буду.kabephe писал(а): В примере библиотеки они не прописаны в явном виде.
RootAdmin писал(а):Ну так у вас степ-дир драйвер. ИМХО - библиотека не для него.
//Определяем пины:
int Motor1EN = 10;
int Motor1dir = 12;
int Motor1step = 9;
void setup ()
{
pinMode(Motor1EN, OUTPUT);
pinMode(Motor1dir, OUTPUT);
pinMode(Motor1step, OUTPUT);
//тут стазу поставим выводы в неактивное состояние
digitalWrite(Motor1EN, LOW);
digitalWrite(Motor1dir, LOW);
digitalWrite(Motor1step, HIGH);
}
void loop ()
{
//тут пишем код, получающий с датчика температуру и прочее.
//по полученной от датчика температуре - рулим мотором так:
//тут вызываем 50 шагов двигателя вперед:
stepMotor1(1, 50);
//пауза
delay (1000);
//тут вызываем 50 шагов двигателя назад:
stepMotor1(0, 50);
//пауза
delay (1000);
//тут вызываем 200 шагов двигателя вперед:
stepMotor1(1, 200);
//пауза
delay (1000);
//тут вызываем 200 шагов двигателя назад:
stepMotor1(0, 200);
//пауза
delay (1000);
}
//То, что дальше - процедура. Пишется ВНЕ основного цикла. Может вызываться из любого места программы.
void stepMotor1(int dir, int step) //dir - направление step -сколько шагов
//Motor1EN - вывод EN 1 драйвера
//Motor1dir - направление первого
//Motor1step - шаг первого
{
//Сначала включим драйвер (Активный уровень ВЫСОКИЙ из даташита)
digitalWrite(Motor1EN, HIGH);
//потоми проверим - какое направление выбрано?
if (dir)
{
//если направление "1" - ставим единицу на выводе Motor1dir
digitalWrite(Motor1dir, HIGH);}
else
//иначе - ставим ноль на выводе Motor1dir
{ digitalWrite(Motor1dir, LOW);}
for (int i=0;i<step; i++)
{
delay(30);
//Поставили ноль на выводе Motor1step (начало импульса), если я верно прочел в даташите "(3) Low‐level pulse duration should > 8μs. Maximum pulse frequency is 50 KHz"
digitalWrite(Motor1step, LOW);
//Пауза (длительность импульса
delay(10);
//Поставили единицу на выводе Motor1step (конец импульса)
digitalWrite(Motor1step, LOW);
}
delay(70); //Пауза чтобы успел шагнуть до выключения питания. Длинная, но... Всегда можно сократить.
digitalWrite(Motor1EN, HIGH);
}
Вернуться в Arduino и другие Xduino
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 14