Как и обещал в прошлой статье, выкладываю код программы для самодиагностики и установки нулевых точек по датчикам. Кстати забыл рассказать о датчиках (концевиках). В качестве концевиков я применил кнопки от старых компьютерных мышек. Подключил их по схеме на рисунке ниже. Подтягивающий резистор имеет номинал 10 кОм.
Эти кнопки достаточно миниатюрны и имеют огромный ресурс - цикл нажатий. Как и любые другие кнопки они не лишены недостатков - так называемого дребезга. Как я с ним борюсь? Да никак. Только в параллель кнопке впаял конденсатор на 1 мкФ.
Эти кнопки достаточно миниатюрны и имеют огромный ресурс - цикл нажатий. Как и любые другие кнопки они не лишены недостатков - так называемого дребезга. Как я с ним борюсь? Да никак. Только в параллель кнопке впаял конденсатор на 1 мкФ.
Конечно это не дает стопроцентной защиты от дребезга контактов но значительно снижает его.
Мной был проведен эксперимент, целью которого была регистрация дребезга. В опытах без конденсатора кнопка меняла свое состояние от трех до семнадцати раз, с конденсатором один- два раза.
В принципе в моем случае с дребезгом можно вообще не бороться, это никак не влияет вообще ни на что. Ну вызвалась функция обработки аппаратного прерывания вместо одно раза - десять раз. И что? Да ничего. Функция обработки прерывания меняет только флаг/переменную (F_Nul_X, F_Nul_Y, F_Nul_Z) с 0 на 1 и все. А все остальное обрабатывается в основном цикле программы. Конечно можно было бы сделать задержку скажем на 50-100 миллисекунд для того чтобы прошел переходной процесс в кнопке и установилось устойчивое состояние 0 или 1, но в функции обработки прерывания не работает delay(). Какая досада, а ведь так хочется. Вот и получается что либо бороться с дребезгом контактов только аппаратными методами либо вообще не бороться.
Ниже представляю код программы в среде Arduino IDE. Постарался все оформить в отдельных функциях и сделать понятные комментарии.
Мной был проведен эксперимент, целью которого была регистрация дребезга. В опытах без конденсатора кнопка меняла свое состояние от трех до семнадцати раз, с конденсатором один- два раза.
В принципе в моем случае с дребезгом можно вообще не бороться, это никак не влияет вообще ни на что. Ну вызвалась функция обработки аппаратного прерывания вместо одно раза - десять раз. И что? Да ничего. Функция обработки прерывания меняет только флаг/переменную (F_Nul_X, F_Nul_Y, F_Nul_Z) с 0 на 1 и все. А все остальное обрабатывается в основном цикле программы. Конечно можно было бы сделать задержку скажем на 50-100 миллисекунд для того чтобы прошел переходной процесс в кнопке и установилось устойчивое состояние 0 или 1, но в функции обработки прерывания не работает delay(). Какая досада, а ведь так хочется. Вот и получается что либо бороться с дребезгом контактов только аппаратными методами либо вообще не бороться.
Ниже представляю код программы в среде Arduino IDE. Постарался все оформить в отдельных функциях и сделать понятные комментарии.
#include <Stepper.h>
// Количество шагов в одном обороте шпинделя
#define STEPS_X 200
#define STEPS_Y 200
#define STEPS_Z 51
// Скорость вращения ШД
#define XSpeed 300
#define YSpeed 300
#define ZSpeed 200
// Выводы для управления ШД по оси Y
#define Xa 23
#define Xb 25
#define Xc 27
#define Xd 29
#define Ya 31
#define Yb 33
#define Yc 35
#define Yd 37
#define Za 39
#define Zb 41
#define Zc 43
#define Zd 45
// Флаги прерываний по осям
volatile boolean F_Nul_X = 0;
volatile boolean F_Nul_Y = 0;
volatile boolean F_Nul_Z = 0;
// Флаги пройденных тестов
int F_Test_XYZ =0;
boolean F_Test_X = 0;
boolean F_Test2_X = 0;
boolean F_Test_Y = 0;
boolean F_Test2_Y = 0;
boolean F_Test_Z = 0;
boolean F_Test2_Z = 0;
Stepper stepperX(STEPS_X, Xa, Xb, Xc, Xd);
Stepper stepperY(STEPS_Y, Ya, Yb, Yc, Yd);
Stepper stepperZ(STEPS_Z, Za, Zb, Zc, Zd);
void setup() {
stepperX.setSpeed(XSpeed);
stepperY.setSpeed(YSpeed);
stepperZ.setSpeed(ZSpeed);
attachInterrupt(2, X_stop, RISING); // инициализация прерываний
attachInterrupt(3, Y_stop, RISING); //
attachInterrupt(4, Z_stop, RISING); //
}
void loop() {
// Проводим прогон и устанавливаем в нулевое положение все оси
if (F_Test_XYZ == 0) {
X_null();
if (F_Test_X == 1 && F_Test2_X ==1) {
stepperX.step(400);
Atermo(Xa, Xb, Xc, Xd);
F_Test_XYZ = 1;
delay(2000); //Задержка-спецэфект :-)
}
}
if (F_Test_XYZ == 1) {
Y_null();
if (F_Test_Y == 1 && F_Test2_Y ==1) {
stepperY.step(400);
Atermo(Ya, Yb, Yc, Yd);
F_Test_XYZ = 2;
delay(2000); //Задержка-спецэфект :-)
}
}
if (F_Test_XYZ == 2) {
Z_null();
if (F_Test_Z == 1 && F_Test2_Z ==1) {
stepperZ.step(-102);
Atermo(Za, Zb, Zc, Zd);
F_Test_XYZ = 3;
delay(2000); //Задержка-спецэфект :-)
}
}
}
// Защита от перегрева ШД по осям
void Atermo(int A, int B, int C, int D) {
digitalWrite(A, LOW); //
digitalWrite(B, LOW); // Устанавливаем 0 по всем
digitalWrite(C, LOW); // входам управления ШД
digitalWrite(D, LOW); //
}
/////////////////////////////////////////
// Установка оси X в нулевое положение //
/////////////////////////////////////////
void X_null() {
if (F_Nul_X == 0 && F_Test2_X == 0) {
stepperX.step(-100);
}
else {
F_Test2_X = 1;
Atermo(Xa, Xb, Xc, Xd);
delay(2000); //Задержка-спецэфект :-)
if (F_Nul_X == 1 && F_Test_X == 0) { // После достижения нулевого положения каретка движется в обратном направлении
for (int i=0; i <= 18; i++) {
stepperX.step(2000);
}
F_Nul_X = 0;
F_Test_X = 1;
F_Test2_X = 0;
Atermo(Xa, Xb, Xc, Xd);
delay(2000); //Задержка-спецэфект :-)
}
}
}
/////////////////////////////////////////
// Установка оси Y в нулевое положение //
/////////////////////////////////////////
void Y_null() {
if (F_Nul_Y == 0 && F_Test2_Y == 0) {
stepperY.step(-100);
}
else {
F_Test2_Y = 1;
Atermo(Ya, Yb, Yc, Yd);
delay(2000); //Задержка-спецэфект :-)
if (F_Nul_Y == 1 && F_Test_Y == 0) { // После достижения нулевого положения каретка движется в обратном направлении
for (int i=0; i <= 18; i++) {
stepperY.step(2000);
}
F_Nul_Y = 0;
F_Test_Y = 1;
F_Test2_Y = 0;
Atermo(Ya, Yb, Yc, Yd);
delay(2000); //Задержка-спецэфект :-)
}
}
}
/////////////////////////////////////////
// Установка оси Z в нулевое положение //
/////////////////////////////////////////
void Z_null() {
if (F_Nul_Z == 0 && F_Test2_Z == 0) {
stepperZ.step(51);
}
else {
F_Test2_Z = 1;
Atermo(Za, Zb, Zc, Zd);
delay(2000); //Задержка-спецэфект :-)
if (F_Nul_Z == 1 && F_Test_Z == 0) { // После достижения нулевого положения каретка движется в обратном направлении
for (int i=0; i <= 22; i++) {
stepperZ.step(-510);
}
F_Nul_Z = 0;
F_Test_Z = 1;
F_Test2_Z = 0;
Atermo(Za, Zb, Zc, Zd);
delay(2000); //Задержка-спецэфект :-)
}
}
}
////////////////////////////////////
// Функции обработчики прерываний //
////////////////////////////////////
void X_stop() {
F_Nul_X = 1;
}
void Y_stop() {
F_Nul_Y = 1;
}
void Z_stop() {
F_Nul_Z = 1;
}
Видеоролик демонстрирует выполнение кода.
Комментариев нет:
Отправить комментарий