Показать сообщение отдельно
Старый 03.04.2016, 11:40   #31
skanch
Модератор
 
Аватар для skanch
 
Регистрация: 19.01.2010
Возраст: 58
Город: Санкт-Петербург
Регион: 78, 98
Сообщений: 2,600
skanch has a brilliant futureskanch has a brilliant futureskanch has a brilliant futureskanch has a brilliant futureskanch has a brilliant futureskanch has a brilliant futureskanch has a brilliant futureskanch has a brilliant futureskanch has a brilliant futureskanch has a brilliant futureskanch has a brilliant future
По умолчанию

"Слепил" скетч управления сервомашинкой с помощью механического энкодера. Энкодер использовал первый попавшийся- выпаял из платы управления магнитолой. За основу взял скетч с этого ресурса. Алгоритм такой:
1.Нажали кнопку один раз-серва повернулась на максимальный угол (сохраненный в памяти).
1.1.Зашли в режим настройки угла сервы (энкодер).
2.Нажали еще раз-серва вернулась в начальную точку.
Угол сохраняется в памяти (Eeprom) и при следующем включении серва повернется на выставленный угол.
Удивительно, но работает...

PHP код:
#define pinA 3  //Первый PIN Сигнала с энкодера 
#define pinB 4  //Второй PIN Сигнала с энкодера 
#define pinC 10 //PIN кнопки запуска системы
#include <Servo.h>
#include <EEPROM.h>
Servo myservo;   //Название сервомашины 
int servoPin 8//Сервомотор подключен на PIN 8 

int angle//Текущий угол поворота (при запуске программы будет автоматический вставать в указаное положение)
int maxAngle 90//Максимальный угол поворота сервомотора (градусов)
int minAngle 6//Минимальный угол поворота сервомотора (градусов)
int angleStep 2;  //Угол единичного шага (градусов)
int stepSpeed 3//Скорость шага (Время задержки шага)
boolean valA=0//Текущее переменное значение энкодера на выходе энкодера А 
boolean valB=0//Текущее переменное значение энкодера на выходе энкодера В
boolean valC=0//Переменная функции запуска системы
boolean Estate=0//Вспомогательная переменная необходимая для определения направления вращения
boolean pulse 0;  //Импульс шага в любом направлении, не стабилизированный
boolean Dir =0//Переменная направления вращения (Если=1 то влево, если=0 то вправо)
boolean zapret=HIGH//Вспомогательная переменная необходимая для стабилизации импульса шага 
boolean outsig=HIGH//Импульс шага в любом направлении, стабилизированный 
long time;  //Переменная таймера задержки в функции стабилизации
int flag 0// Флаг состояния
int regim 0// Переключалка

void setup()
{
angle EEPROM.read(0);//Считываем из памяти угол поворота сервы
pinMode(pinC,INPUT_PULLUP);  //Цифровой вход С кнопки запуска системы
pinMode(pinA,INPUT_PULLUP);  //Цифровой вход A c энкодера 
pinMode(pinB,INPUT_PULLUP);  //Цифровой вход В c энкодера


void loop()
{
if(
digitalRead(pinC) == LOW && flag == 0)//Если кнопка нажата   
     // и перемення flag равна 0 , то ...  

regim ++;
flag 1;//Это нужно для того что бы с каждым нажатием кнопки 
        //происходило только одно действие 

if(regim 4// Если номер режима превышает требуемого
// то отсчет начинается с 1
regim 1;
}
}
if(
digitalRead(pinC) == HIGH && flag == 1)//если кнопка НЕ нажата 
     //и переменная flag равна - 1 ,то ... 
{
flag 0;
}

// РЕЖИМ 1: 

if(regim == 1)// Нажали кнопку один раз...
{
   
myservo.attach(servoPin);
 
myservo.write(angle); // Серва повернулась на сохраненный в Eeprom угол
delay(stepSpeed);// Скорость поворота сервы
}
// РЕЖИМ 2: 
if(regim ==)// Нажали кнопку второй раз...
{
  
change_ugol(); // Режим установки наклона с помощью энкодера
 
}
 
// РЕЖИМ 3: 
if(regim == 3)// Нажали кнопку в третий раз...
{
 }
// ничего не происходит...

// РЕЖИМ 4: 
if(regim == 4)// Нажали кнопку в четвертый раз...
{
  
myservo.write(maxAngle); // Серва вернулась в исходное состояние
delay(stepSpeed);// Скорость поворота сервы
 
}
   }

// РЕЖИМ УСТАНОВКИ УГЛА НАКЛОНА С ПОМОЩЬЮ ЭНКОДЕРА
void change_ugol()
{
valA=digitalRead(pinA); //Читает и запоминает текущее состояние на выходе энкодера (Выход А)  
valB=digitalRead(pinB); //Читает и запоминает текущее состояние на выходе энкодера (Выход В)
valC=digitalRead(pinC); //Читает и запоминает текущее состояние кнопки быстрой центровки

//РАСПОЗНАНИЕ ШАГА 
if(valA+valB==HIGH){pulse=1;} //Определяет шаг и дает не стабилизированный импульс шага 
else{pulse=0;}

//СТАБИЛИЗАТОР ИМПУЛЬСА ШАГА
if((pulse==HIGH)&&(zapret==LOW))//Условие работы стабилизатора выходного импульса

time millis();  //Запуск таймера
outsig HIGH//Стабилизированый выходной импульс шага
 

zapret=HIGH;
if(
outsig && (millis() - time) > 1//(2)-Временная длинна выходного импульса
{
  
outsig LOW;//Остановка таймера
  


if(
pulse==LOW)

zapret=LOW//Антидребезг
}
//ОПРЕДЕЛЕНИЕ ВСПОМОГАТЕЛЬНОЙ ПЕРЕМЕННОЙ
//ДЛЯ ОПРЕДЕЛЕНИЯ НАПРАВЛЕНИЯ ВРАЩЕНИЯ
if((valA==LOW)&&(valB==LOW)&&(valA<1)&&(valB<1)) 
{
  
Estate=1;//Вспомогательная переменная для определения направления вращения энкодера на (+) 
  

if((
valA==HIGH)&&(valB==HIGH)&&(valA>0)&&(valB>0))
{
  
Estate=0;//Вспомогательная переменная для определения направления вращения энкодера на (-)
  


//ОПРЕДЕЛЕНИЕ НАПРАВЛЕНИЯ ВРАЩЕНИЯ 
if(((Estate==1)&&(valA==LOW)&&(valB==HIGH))||((Estate==0)&&(valA==HIGH)&&(valB==LOW))) //Условия направления вращения(+)
{
  
Dir=1;//Направление вращения (+)
  
}  
if(((
Estate==1)&&(valA==HIGH)&&(valB==LOW))||((Estate==0)&&(valA==LOW)&&(valB==HIGH))) //Условия направления вращения(-)
{
  
Dir=0;//Направление вращения(-)
  
}  

//ВЫХОДНОЙ СИГНАЛ
if((Dir==1)&&(outsig==HIGH))  //Условие поворота в одну из строн (Направление + стабилизированый сигнал шага)
{
  
angle=angle+angleStep//угол поворота сервомотора меняется по шагово на заданную величину шага 
if (angle maxAngle)
{
  
angle=maxAngle;//Ограничитель угла поворота исполнительного устройства (Рабочий диапозон)
  
}
 }  
if((
Dir==0)&&(outsig==HIGH))  //Все тоже самое как для предидущей функции но с !инверсией
{
  
angle=angle-angleStep//угол поворота сервомотора меняется по шагово на заданную величину шага 
if (angle minAngle)
{
  
angle minAngle//Ограничитель угла поворота исполнительного устройства (Рабочий диапозон) 
  
}
 } 
{
  
myservo.write(angle);  //Входной сигнал на сервомотор
delay(stepSpeed);//Скорость шага (время задержки шага)
}  
EEPROM.write(0angle); //Сохраним в памяти угол поворота

Миниатюры
Нажмите на изображение для увеличения
Название: Encoder.jpg
Просмотров: 853
Размер:	281.8 Кб
ID:	43331   Нажмите на изображение для увеличения
Название: Encoder1.JPG
Просмотров: 498
Размер:	90.8 Кб
ID:	43334  

Последний раз редактировалось skanch; 04.04.2016 в 02:25.
skanch вне форума   Ответить с цитированием