PCCar.ru - Ваш автомобильный компьютер

PCCar.ru - Ваш автомобильный компьютер (http://pccar.ru/index.php)
-   Сделай сам (http://pccar.ru/forumdisplay.php?f=17)
-   -   Система перемещения монитора (http://pccar.ru/showthread.php?t=22812)

skanch 03.04.2016 11:40

Вложений: 2
"Слепил" скетч управления сервомашинкой с помощью механического энкодера. Энкодер использовал первый попавшийся- выпаял из платы управления магнитолой. За основу взял скетч с этого ресурса. Алгоритм такой:
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); //Сохраним в памяти угол поворота



skanch 03.04.2016 19:10

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

PHP код:

#define pinA 3  //Первый PIN Сигнала с энкодера 
#define pinB 4  //Второй PIN Сигнала с энкодера 
#include "ClickButton.h"
#include <Servo.h>
#include <EEPROM.h>
Servo myservo;   //Название сервомашины 
int servoPin 8//Сервомотор подключен на PIN 8 
int angle//Текущий угол поворота (при запуске программы будет автоматический вставать в указаное положение)
int maxAngle 90;   //Максимальный угол поворота сервомотора (градусов)
int minAngle =45//Минимальный угол поворота сервомотора (градусов)
int angleStep 2;  //Угол единичного шага (градусов)
int stepSpeed 2//Скорость шага (Время задержки шага)
boolean valA=0//Текущее переменное значение энкодера на выходе энкодера А 
boolean valB=0//Текущее переменное значение энкодера на выходе энкодера В
boolean Estate=0//Вспомогательная переменная необходимая для определения направления вращения
boolean pulse 0;  //Импульс шага в любом направлении, не стабилизированный
boolean Dir =0//Переменная направления вращения (Если=1 то влево, если=0 то вправо)
boolean zapret=HIGH//Вспомогательная переменная необходимая для стабилизации импульса шага 
boolean outsig=HIGH//Импульс шага в любом направлении, стабилизированный 
long time;  //Переменная таймера задержки в функции стабилизации
// Светодиод
const int ledPin 13;
int ledState 0;
// Кнопка
const int buttonPin1 10;
ClickButton button1(buttonPin1LOWCLICKBTN_PULLUP);
// Назначаем функцию переключателя
int LEDfunction 0;

void setup()
{
  
angle EEPROM.read(0);//Считываем из памяти угол поворота сервы
  
pinMode(ledPin,OUTPUT);  
  
button1.maxPresses     9;    // Количество программируемых нажатий для кнопок
  
button1.debounceTime   20;   // Таймер дребезга в мс
  
button1.multiclickTime 350;  // Пауза между нажатиями кнопки
  
button1.heldDownTime   1000// длительность нажатия и удержания кнопки
  
pinMode(pinA,INPUT_PULLUP);  //Цифровой вход A c энкодера 
  
pinMode(pinB,INPUT_PULLUP);  //Цифровой вход В c энкодера
 
}
void loop()
{
 
// Обновлям состояние кнопки
  
button1.Update();
  
  if (
button1.click != 0)
  
  
LEDfunction button1.click;
  if(
button1.click == 1
  
ledState = !ledState;
  
//Два коротких нажатия
  
if(LEDfunction == 2
   {
  
myservo.attach(servoPin);
  
myservo.write(maxAngle); // Серва вернулась в исходное состояние
  
delay(stepSpeed);// Скорость поворота сервы
   
}
  
 
  
// три коротких нажатия
  
if(LEDfunction == 3
  {
  
myservo.attach(servoPin);
  
change_ugol(); // Режим установки наклона с помощью энкодера
  
}
  

  
// длительное однократное нажатие (более 1 секунды)
  
if(LEDfunction == -1)
  {
  
myservo.attach(servoPin);
  
myservo.write(angle); // Серва повернулась на сохраненный в Eeprom угол
  
delay(stepSpeed);// Скорость поворота сервы
  
}
  

  
// одно короткое + одно длительное нажатие (более 1 секунды)
  
if(LEDfunction == -2)
   {}
//можно что-то вставить

   
// два коротких + одно длительное  нажатие (более 1 секунды)
  
if(LEDfunction == -3
  {}
//можно что-то вставить
// update the LED
  
digitalWrite(ledPin,ledState);
  }

  
//*********** РЕЖИМ УСТАНОВКИ УГЛА НАКЛОНА С ПОМОЩЬЮ ЭНКОДЕРА **************//

void change_ugol()
{
valA=digitalRead(pinA); //Читает и запоминает текущее состояние на выходе энкодера (Выход А)  
valB=digitalRead(pinB); //Читает и запоминает текущее состояние на выходе энкодера (Выход В)

//РАСПОЗНАНИЕ ШАГА 
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); //Сохраним в памяти угол поворота



skanch 03.05.2016 13:09

Спрошу в своей теме...
Нужен компактный осевой мотор-редуктор . Диаметр корпуса не должен превышать 10 мм. Редуктор желателен планетарный.
Скорость: 4-10 оборотов в минуту. Усилие на валу: от 1500 г/см. Длинна всего мотора до 100 мм. Нужен для изготовления электропривода декоративной крышки механизма перемещения монитора (принцип, как на видео). Все время пользовался Shayang Ye IG-12GM DC с диаметром корпуса 12 мм. Но сейчас нужен именно не более 10 мм и со схожими параметрами с IG-12GM. Возможно, кто-то из заглянувших в мою тему сможет подсказать - где приобрести такой.

skanch 08.05.2016 23:55

Вложений: 4
Ломаем (модернизируем) дальше сервомотор...
Из-за того, что оси валов пересекаются под углом в 90 градусов я в своих механизмах использую коническую передачу. Коническая шестерня, та что на серве, располагается консольно. При этом, вследствие повышенной деформации консольного вала (один из побочных эффектов конической передачи), увеличивается неравномерность распределения нагрузки по ширине зубчатого венца и как следствие - выход одного подшипника сервомотора из строя - того, что ближе и меньше по размеру на фото. Появляется значительный люфт у "подиума" в открытом состоянии. Подшипник, прямо скажу - слабоват для заявленного усилия в 53кг/см. Подобрать что-то более надежное для замены вряд ли получится. Думаю сделать небольшой промежуточный редуктор с более мощными подшипниками и перенести осевую нагрузку с подшипника сервы.
Позже поделюсь результатом.

skanch 20.05.2016 21:30

Вложений: 5
Вот собственно и редуктор...

skanch 25.05.2016 18:39

Вложений: 2
Нашел миниатюрный мотор с редуктором. Правда не с планетарным... и немного не те размеры, но думаю, что подойдет.
Практически бесшумный. При питании от 5 вольт скорость примерно 6-7 оборотов в минуту и ток при нагрузке в 2 кг./см. - 18-20 мА. Заявленное усилие на валу - 3 кг./см.(похоже на правду). Габариты 12 мм. Х 10 мм. Х 40 мм. Диаметр вала - 3 мм. Ну и до кучи прикупил подшипники... Буду пытаться сделать "управляемую" крышку для корпуса механизма.

skanch 25.05.2016 19:39

Вложений: 2
Сделал новую плату управления под размер нового редуктора. Весь механизм увеличился в ширину - это не критично, место установки позволяет. Главное размер в высоту остается 50 мм.

skanch 25.05.2016 20:12

Вложений: 3
Очередная примерка на заготовке каретки.

skanch 31.05.2016 18:18

Вложений: 4
Купил неплохой, на мой взгляд, мотор с червячным редуктором и с энкодером. Енкодер построен на датчике Холла .
Буду пытаться программно "прикрутить" к своим поделкам.

skanch 26.06.2016 19:58

Вложений: 1
Цитата:

Сообщение от skanch (Сообщение 345990)
Это "пациент".

Так выглядит сейчас.


Часовой пояс GMT +4, время: 02:55.

Работает на vBulletin® версия 3.8.4.
Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.
Перевод: zCarot