Показать сообщение отдельно
Старый 05.03.2017, 19:10   #1
BNSF9399
Местный
 
Аватар для BNSF9399
 
Регистрация: 06.03.2014
Адрес: Москва
Сообщений: 1,741
Сказал(а) 'не согласен(а)'!: 5
Сказали 'не согласен'! 9 раз(а) в 7 сообщениях
Сказал(а) спасибо: 553
Поблагодарили 2,794 раз(а) в 755 сообщениях
Все 'Спасибо' этого пользователя. :
0 за это сообщение
0 Всего
Репутация: репутация неоспорима (2791)
По умолчанию Управление сервами от кнопок (для аналогового макета)

Дело было в выходной...
Делать было нечего...
Пусть и не складно, но по теме
Накидал скетч управления тремя сервами с трех кнопок с отображением положения стрелки.
Может и было уже, но интересно было самому поиграться, да и камрад на соседнем форуме озадачился таким девайсом для своего аналогового макета. В принципе, ничего не мешает и на цифровом его использовать, но без управления от КС.
При включении - сервы выворачивает в последнее состояние (если вдруг их свернули)
"Грабли" обнаружены одни, при переводе из положения 0 (угол не важен, при любых раскладах, когда запускается поворот на увеличение угла) сначала идет небольшой отскок назад.
Как говорил один мой знакомый: "Это баг, которы вовсе не баг, потому что в скрипах все правильно".
Грешу на сервы...
Сори, комменты кривые, особенно с реверсом, но думаю мысль понятна. Смысл тот же, что у местного ServoMotion.
Код:
//подключаемые библиотеки
#include <EEPROM.h>
#include <Bounce2.h>
#include <Servo.h>

//переменные конфигурации
int servoAngles[][2]={{0,90},{0,90},{0,90}}; // углы отклонения сервоприводов {"прямо", "в бок"}
byte servoReverce[]={0,0,0}; //реверс углов сервоприводов (если в положении "прямо" угол задан во втором элементе предыдущего массива, то поставить 1.)
int servoSpeed[]={10,10,10}; //скорость вращения сервопривода. указано количество миллисекунд поаорота на 1 градус

//переменные определяюще ножки подключения
int normalLed[]={8,10,12}; //ножки подключения светодиода показывающего прямое положение стрелки
int routeLed[]={9,11,13}; //ножки подключения светодиода показывающего положение стрелки "в бок"
int servoPins[]={3,5,6}; //ножки подключения провода управления сервопривода
int buttonPins[]={2,4,7}; //ножки подключения кнопок переключения

//переменные используемые при повороте сервопривода
byte CurrentPosition[]={0,0,0}; //текущее положение сервопривода. 0=прямо, 1=в бок.
int currentAngle[]={0,0,0};//текущий угол поворота сервопривода
unsigned long nextTime[]={0,0,0};// время следующего поворота на 1 градус
unsigned long currentTime; //текущее время
byte dir;// направление поворота сервопривода

//объекты сервоприводов и антидребезка кнопок
const int servos=sizeof(servoPins)/sizeof(int);
Servo servoServos[servos];
Bounce servoBouncer[servos];

void setup() {
  for(int i=0;i<servos;i++){
    pinMode(buttonPins[i], INPUT);
    servoBouncer[i] = Bounce();
    servoBouncer[i].attach(buttonPins[i]);
    servoBouncer[i].interval(5);
    pinMode(normalLed[i], OUTPUT);
    pinMode(routeLed[i], OUTPUT);
    if(EEPROM.read(i) > 1){
      EEPROM.update(i,0);
    }
    CurrentPosition[i]=EEPROM.read(i);
    digitalWrite(normalLed[i], !CurrentPosition[i]);
    digitalWrite(routeLed[i], CurrentPosition[i]);
    servoServos[i].attach(servoPins[i]);
    if(servoReverce[i]){
      servoServos[i].write(servoAngles[i][!CurrentPosition[i]]);
      currentAngle[i]=servoAngles[i][!CurrentPosition[i]];
    }
    else {
      servoServos[i].write(servoAngles[i][CurrentPosition[i]]);
      currentAngle[i]=servoAngles[i][CurrentPosition[i]];
    }
  }
  delay(1000);
  for(int i=0;i<servos;i++){
    servoServos[i].detach();
  }
}

void loop() {
  currentTime=millis();
  for(int i=0;i<servos;i++){
    if(nextTime[i]>0 && nextTime[i]<currentTime){
      if(currentAngle[i]>=servoAngles[i][0] && currentAngle[i]<=servoAngles[i][1]){
        nextTime[i]=currentTime+servoSpeed[i];
        if(servoReverce[i]){
          dir=!CurrentPosition[i];
        }
        else {
          dir=CurrentPosition[i];
        }
        if(dir){
          currentAngle[i]++;
        }
        else {
          currentAngle[i]--;
        }
        if(servoAngles[i][1]/currentAngle[i] == 2 || servoAngles[i][1]/currentAngle[i] == 2.5 ){
          digitalWrite(normalLed[i], !CurrentPosition[i]);
          digitalWrite(routeLed[i], CurrentPosition[i]);
        }
        servoServos[i].write(currentAngle[i]);
      }
      else{
        nextTime[i]=0;
        servoServos[i].detach();
      }
    }
    if(servoBouncer[i].update()){
      if(servoBouncer[i].read()==LOW){
        CurrentPosition[i]=!CurrentPosition[i];
        EEPROM.update(i,CurrentPosition[i]);
        nextTime[i]=currentTime;
        if(servoReverce[i]){
          currentAngle[i]=servoAngles[i][CurrentPosition[i]];
        }
        else {
          currentAngle[i]=servoAngles[i][!CurrentPosition[i]];
        }
        servoServos[i].attach(servoPins[i]);
      }
    }
  }
}
Схема
Нажмите на изображение для увеличения
Название: servo_bb.jpg
Просмотров: 1858
Размер:	160.6 Кб
ID:	140741
Можно и Arduino Pro Mini использовать, по ногам вроде как совпадает она с Uno.
Видео работы.
BNSF9399 вне форума  
Вверх
15 пользователя(ей) сказали cпасибо: