цикличная работа сервопривода

Тема в разделе "Arduino & Shields", создана пользователем piter pen, 16 ноя 2017.

  1. akl

    akl Гуру

    блютус-приложения обычно при удержании кнопки отправляют команду сколько-то раз в секунду. надо учитывать это в таймерах логики
     
    piter pen нравится это.
  2. piter pen

    piter pen Нерд

    воооо! теперь разобрался. а теперь простите меня))) вопросов все больше появляется... сейчас у меня получилось реализовать движение в одном направлении. т.е. когда подаю питание, серва встает в 90градусов
    и по нажатию кнопки идет к 0. а как лучше будет реализовать обратное вращение? что бы по нажатию другой кнопки (получения другой команды) шла в сторону 180 градусов. как я понимаю класс для этого необязательно переписывать?
     
  3. piter pen

    piter pen Нерд

    блин... существенно упала скорость вращения... это блютуз так тормозит? или код подчищать надо? хотя я думаю можно подобрать параметрами необходимую скорость вращения
     
  4. akl

    akl Гуру

    а что конкретно надо? просто крутить серву кнопками с телефона?
    проще всего так (одна кнопка влево другая врпаво
    while (Serial1.available() > 0) {
    char cmd = Serial.read();
    if(cmd=='команда1'){
    if (pos < MAX-d) { servo.write(pos + d); }
    }
    else if(cmd=='команда2'){
    if (pos > MIN+d) { servo.write(pos - d); }
    }
    }

    если в цикле нет задержек, то максимальная скорость будет ограничена частотой, с которой шлет букву блютус-приложение. можно увеличить скорость увеличив d, но точность позиции уменьшится
     
  5. akl

    akl Гуру

    можно сделать подругому - крутить серву автономно, переставая крутить по таймеру через время, большее чем период прихода буквы, а по приходу буквы обновлять таймер. но не факт что это будет лучше.
     
  6. piter pen

    piter pen Нерд

    ваш пример подходит для 1 сервы...ну или несколько... в моем случае 18 как минимум... поэтому с классами будет компактнее. я так думаю)))) если 18 штук разбить по классам... сейчас разбираюсь в деталях кода, поскольку хочу написать его основываясь на инверсную кинематику... (с сыном строим гексапод). тот код который есть сейчас крайне примитивен
    хотя вашу идею можно попробовать запихнуть в мой скетч.
     
  7. akl

    akl Гуру

    гексаподы ардуиновые должны быть широко распространены - надо взять готовый проект и покурить его как следует.
     
  8. piter pen

    piter pen Нерд

    я пробовал... но на инверсной кинематике исходников по пальцам перечесть... а точнее, первый раз натолкнулся на подобный буквально на днях . и для меня разбор по полочкам чужого скетча - задача не их простых на данный момент. и то там в кинематике задействованы опорные датчики давления на каждой ноге что усложняет код. так что пока мне это в одиночку не выкурить)))
     
  9. akl

    akl Гуру

    лично я бы лучше сделал на колесах, но зато чтоб стреляло :D
     
  10. piter pen

    piter pen Нерд

    ну это дело вкуса)))
    кстати.. по поводу покурить готовый проект.. а не проще будет ли мне организовать управление по i2c? так сказать подогнать железо по готовый скетч?
     
  11. piter pen

    piter pen Нерд

    Подскажите пожалуйста, что в скетче не так?
    первая кнопка уже не работает, вторая - еще не работает
    Код (C++):
    #include <SoftwareSerial.h>
    #include <Servo.h>
    #include <String.h>
    SoftwareSerial BT(11, 10); //TX, RX respetively
    String voice;
    int i;
    int val = 0;

    class Sweeper
    {
        Servo servo; // сервопривод
        int pos; // текущее положение сервы
        int increment; // увеличиваем перемещение на каждом шаге
        int updateInterval; // промежуток времени между обновлениями
        unsigned long lastUpdate; // последнее обновление положения
      public:
        Sweeper(int interval)
        {
          updateInterval = interval;
          increment = 10;
        }
        void Attach(int pin)
        {
          servo.attach(pin);
        }
        void Detach()
        {
          servo.detach();
        }
        void Update()
        {
          if ((millis() - lastUpdate) > updateInterval) // время обновлять
          {
            lastUpdate = millis();
            pos += increment;
            servo.write(pos);
            Serial.println(pos);

            int minServo, maxServo;
            minServo = 5;
            maxServo = 175;
            if ((pos >= maxServo) || (pos <= minServo)) // конец вращения
            {
              if (voice == "1")
                if (pos + increment < minServo)
                  pos = minServo;
              // обратное направление
              increment = -increment;
            }
            {
              if (voice == "2")
                if (pos - increment > maxServo)
                  pos = maxServo;
              // обратное направление
              increment = -increment;
            }
          }
        }
    };

    Sweeper sweeper1(10);
    Sweeper sweeper2(10);
    Sweeper sweeper3(10);

    void setup()
    {
      sweeper1.Attach(8);
      sweeper2.Attach(9);
      sweeper3.Attach(10);

      BT.begin(9600);
      Serial.begin(9600);

    }

    void loop()
    {
      while (BT.available())//Check if there is an available byte to read
      { delay(10); //Delay added to make thing stable
        char c = BT.read(); //Conduct a serial read
        if (c == '#')
        {
          break; //Exit the loop when the # is detected after the word
        }
        voice += c; //Shorthand for voice = voice + c
      }
      voice.toLowerCase();
      if (voice.length() > 0) {
        val--;
      } else {
        val++;
      }
      {
        Serial.println(voice);

        if ( voice == "1")
        {
          sweeper1.Update();
          sweeper2.Update();
          sweeper3.Update();
        }

        if ( voice == "2")
        {
          sweeper1.Update();
          sweeper2.Update();
          sweeper3.Update();
        }

        voice = "";
      }

    }