расслабление сервы

SLOM
Offline
Зарегистрирован: 06.11.2014

Всем привет, создал тему т.к ненашел нигде чтобы ктото такое делал. 

 

смысл вот в чем. 

сейчас у меня при нажатии на кнопку на серву приходит сигнал сдвинуться на 0,012, если зажать кнопку то эти дискретные значения сумируються и в итоге серва может уйти до предела. 

но серва стоит в манипуляторе: 

и когда клешня сжимает предмет, серва остаеться в напряжении, делая попытки двигаться дальше.  т.к. допустим предмет попался на 45градусах, а команда с пульта пришла закрываться до 100град.  серва начинает жрать ток, греться, одна так уже сгорела! 

чтобы обезопасить сервы от перегрузки, но в тоже время сохранить функционал, я придумал что немешало бы их "расслоблять" 

а именно после каждого отпускания кнопки делать короткое, незаметное глазу движение в обратную сторону, тем самым сбрасывая "желание" сервы двигаться вперед. 

при таком раскладе серва продолжит удерживать предмет в клешне но небудет жрать ток и греться. 

 

это я проверил эксперементально, зажимаю кнопку на пульте, клешня сжимает предмет, и продолжает давить, идет просадка по питанию, быстро нажимаю на кнопку разжимания, визуально серва даже не двинулась, но при этом перестала давить и ток в норме, просадка ушла... 

 

помогите это запрограмить. мои попытки не увенчались успехом. 

мот мой код: 

// Скетч для управления через блютус, Wild Thumper 6WD, на ардуино совместимом контролере TREX controller. реализовано движение и стрельба с водомета. 


#include <BTCA2ALite.h>// Добавляем библиотеку блютус программы
#include <Servo.h> // Добавляем библиотеку серво

Servo myservoH; // Горизонтальная серва углы от 0 до 180 (центровка 89)
Servo myservoV; // Вертикальная серва углы от 1 до 45
const int H_SERVO_PIN = 5; // Горизонтальная серва подключена к пину 7
const int V_SERVO_PIN = 8; //Пин вертикального сервопривода 8
const float H_L_ANGLE = 116; // Максимальные угл поворота башни налево
const float H_R_ANGLE = 45; // Максимальные угл поворота башни направо
const float H_DEF_ANGLE = 38; // Дефолтный угол (центровка)
const float V_U_ANGLE = 120; // Максимальные угл поворота башни вверх
const float V_D_ANGLE = 0; // Максимальные угл поворота башни вниз
const float V_DEF_ANGLE = 90; // Дефолтный угол (центровка)
//Размер шага V_STEP и H_STEP побираем экспериментально для достижения нужной скорости поворота серв
const float V_STEP = 0.012; // Шаг - знаение отвечающее за скорость вращения по вертикали.
const float H_STEP = 0.012; // Шаг - знаение отвечающее за скорость вращения по горизонтали
float curVAngle = V_DEF_ANGLE; //Переменная текущего угла верт. сервы
float curHAngle = H_DEF_ANGLE; //Переменная текущего угла гор. сервы
bool moveServoVUp = false; //Флаг движения верт. сервы вверх
bool moveServoVDown = false; //Флаг движения верт. сервы вниз
bool moveServoHLeft = false; //Флаг движения гор. сервы влево
bool moveServoHRight = false; //Флаг движения гор. сервы вправо

btca2aLite btca2aLite; // Конструктор btca2aLite


// задаем пины для левого мотора
#define Dir_L 2
#define Pwm_L 3
#define Brake_L 4
// задаем пины для правого мотора
#define Dir_R 10
#define Pwm_R 11
#define Brake_R 9

// Задаем скорости для движения
byte MaxSpeed = 250; // Максимальная скорость
byte MinSpeed = 100;  // Минимальная скорость

int forw_back = 0;
int righ_left = 0;

byte step_fb = 5;     // Шаг изменения скорости движения вперед - назад
byte step_stop = 10;  // Шаг изменения скорости остановки
byte step_rl =  20;    // Шаг изменения скорости движения вправо - влево
byte step_dir = 10;   // Шаг изменения скорости выравнивания



#define SHOT  12 // пин для водомета

enum States
{
    WAITING,
    READING,
    RUNNING,
    ERROR,
    TIMEOUT
};

States state;
States onWait();
States onRead();
States onRun();
States onError();

States onTimeout();

void performServo(); // добовляем сервы


void setup(){
    Serial.begin(9600); // Скорость BT и порта должна быть 9600
    //Моторы
    pinMode (Pwm_L, OUTPUT);
    pinMode (Dir_L, OUTPUT);
    pinMode (Brake_L, OUTPUT);
    
    pinMode (Pwm_R, OUTPUT);
    pinMode (Dir_R, OUTPUT);
    pinMode (Brake_R, OUTPUT);
    
    digitalWrite (Pwm_L, LOW);
    digitalWrite (Pwm_R, LOW);
    
    digitalWrite (Brake_L, LOW);
    digitalWrite (Brake_R, LOW);
  
 pinMode(SHOT, OUTPUT); // задаем выход для стрельбы водой
    
    // устанавливаем пин как вывод управления сервой
    myservoH.attach(H_SERVO_PIN);
    myservoV.attach(V_SERVO_PIN);
    myservoH.write(curHAngle);
    myservoV.write(curVAngle);
    
    
    //Светодиод
    pinMode(13, OUTPUT); // Инициализируем пин светодиода
    digitalWrite(13, HIGH); // Светодиод выключен
}

void loop(){
    
    btca2aLite.ReadCommand(); // Считывание принятых команд (кодов кнопок)
    //Вызываем функцию управление сервами
    performServo();
    

  static unsigned long pre_millis = 0;
  if(millis()-pre_millis > 50)
  {
    pre_millis = millis();
    
    if(btca2aLite.ButtonPressed(KEYCODE_DPAD_UP)) 
    {
      forw_back += step_fb;
      if(forw_back > 0 && forw_back < MinSpeed) forw_back = MinSpeed;
    }
    else if(btca2aLite.ButtonPressed(KEYCODE_DPAD_DOWN)) 
    {
      forw_back -= step_fb;
      if(forw_back < 0 && forw_back > MinSpeed*-1) forw_back = MinSpeed*-1;
    }
    else 
    {
      if(forw_back < 0) forw_back += step_stop;
      else if(forw_back > 0) forw_back -= step_stop;
      if(abs(forw_back) < MinSpeed) forw_back = 0;
    }
    forw_back = constrain(forw_back, MaxSpeed*-1, MaxSpeed);


    if(btca2aLite.ButtonPressed(KEYCODE_DPAD_RIGHT)) 
    {
      righ_left += step_rl;
      if(righ_left > 0 && righ_left < MinSpeed) righ_left = MinSpeed;
    }
    else if(btca2aLite.ButtonPressed(KEYCODE_DPAD_LEFT)) 
    {
      righ_left -= step_rl;
      if(righ_left < 0 && righ_left > MinSpeed*-1) righ_left = MinSpeed*-1;
    }
    else 
    {
      if(righ_left < 0) righ_left += step_dir;
      else if(righ_left > 0) righ_left -= step_dir;
      if(abs(righ_left) < MinSpeed) righ_left = 0;
    }
    righ_left = constrain(righ_left, MaxSpeed*-1, MaxSpeed);


    int pwm_l = forw_back + righ_left;
    int pwm_r = forw_back - righ_left;
    pwm_l = constrain(pwm_l, MaxSpeed*-1, MaxSpeed);
    pwm_r = constrain(pwm_r, MaxSpeed*-1, MaxSpeed);

    digitalWrite(Dir_L, (pwm_l<0)?0:1);
    digitalWrite(Dir_R, (pwm_r<0)?0:1);
    analogWrite(Pwm_L, abs(pwm_l));
    analogWrite(Pwm_R, abs(pwm_r));
  }
        
  
    
    //-------— включение насоса —-------------
   if (btca2aLite.ButtonPressed(KEYCODE_BUTTON_SELECT))
    { 
     digitalWrite (SHOT, HIGH);
     }
    //-------— выключение насоса происходит автоматически после отпускания кнопки—------------- 
   if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_SELECT))
    {
   digitalWrite (SHOT, LOW);
    } 
    
    
    //--------— Повороты серв при нажатии кнопок —-------------
    
    if(btca2aLite.Button(KEYCODE_BUTTON_X)) // servoV вниз
    {
        moveServoVDown = true;
              
    }
    if(btca2aLite.Button(KEYCODE_BUTTON_A)) // servoH движется к 0
    {
        moveServoHRight = true;
    }
    if(btca2aLite.Button(KEYCODE_BUTTON_B)) // servoV вверх
    {
        moveServoVUp = true;
              
    }
    
    if(btca2aLite.Button(KEYCODE_BUTTON_Y)) // servoH движется к 180
    {
        moveServoHLeft = true;
    }
    
//--------— чтобы сервы не продолжали движения при отжатых кнопках —-------------    
if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_X))
{
 moveServoVUp = true;
  moveServoVDown = false;
}
if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_B))
{
  moveServoVDown = true;
moveServoVUp = false;
}

if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_A))
{
  moveServoHLeft = true;
moveServoHRight = false;
}
if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_Y))
{
  moveServoHRight = true;
moveServoHLeft = false;
}
    
    
    //----------------— Стоп —---------------------
    
    // Если не нажата ни одна кнопка курсора происходит остановка, скорость 0 для каждого мотора
    if (btca2aLite.ButtonReleased(KEYCODE_DPAD_UP) && btca2aLite.ButtonReleased(KEYCODE_DPAD_DOWN) && btca2aLite.ButtonReleased(KEYCODE_DPAD_LEFT) && btca2aLite.ButtonReleased(KEYCODE_DPAD_RIGHT)){
        analogWrite (Pwm_L, 0);
        analogWrite (Pwm_R, 0);
    }
}



//Функция управления сервоприводами (вызывается в теле loop на каждой итерации)
//Выполняет изменения положения серв на подобранный шаг согласно установленным флагам движения
//Флаги устанавливаются согласно поступившим символам управления сервами
void performServo()
{
    //Установлен флаг движения вверх и текущий угол не максимальный
    if (moveServoVUp && curVAngle + V_STEP <= V_U_ANGLE)
    {
        //К текущему верт. углу прибавляем шаг
        curVAngle += V_STEP;
    }
    //Установлен флаг движения вниз и текущий угол не минимален
    else if (moveServoVDown && curVAngle - V_STEP >= V_D_ANGLE)
    {
        //От текущего верт. угла отнимаем шаг
        curVAngle -= V_STEP;
    }
    //Установлен флаг движения влево и текущий угол не максимален
    if (moveServoHLeft && curHAngle + H_STEP <= H_L_ANGLE)
    {
        //К текущему гор. углу прибавляем гор. шаг
        curHAngle += H_STEP;
    }
    //Установлен флаг движения вправо и текущий угол не минимален
    else if (moveServoHRight && curHAngle - H_STEP >= H_R_ANGLE)
    {
        //От текущего угла отнимаем гор. шаг
        curHAngle -= H_STEP;
    }
    
    //Если было движние по вертикали
    if (moveServoVUp || moveServoVDown)
    {
        myservoV.write(curVAngle);
    }
    //Если было движение по горизонтали
    if (moveServoHLeft || moveServoHRight)
    {
        myservoH.write(curHAngle);
    }
}

 

вот в этом месте 

 

//--------— чтобы сервы не продолжали движения при отжатых кнопках —-------------    
if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_X))
{
 moveServoVUp = true;
  moveServoVDown = false;
}
if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_B))
{
  moveServoVDown = true;
moveServoVUp = false;
}

if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_A))
{
  moveServoHLeft = true;
moveServoHRight = false;
}
if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_Y))
{
  moveServoHRight = true;
moveServoHLeft = false;
}

    

недолжно было быть  moveServoVUp = true;  и других... это я добавил думая что при отпускании кнопки вначале серва сделает шаг назад а потом стоп, но по факту она стала постоянно открываться. 

 

может какието знаки припинания надо поставить ? :)

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

может просто датчик тока поставить. ток вырос значит хватит

или измерять питание сервы. питание черзе резистор низкоомный. просадка появилась значит стоп. только питание сервы и ардуины должно быть раздельное. отдельный стабилизатор просто на серву

SLOM
Offline
Зарегистрирован: 06.11.2014

может датчик тока и просто поставить, но его у меня нет, делать раздельное питание и прочие танцы с бубном тоже очень геморно. 

на то ведт он и ардуино что все можно запрограмировать, тем более что в моем случае проблема не в питании и не в серве, а именно в мозгах! 

 

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

этого же эффекта и я хочу добиться. 

клешня сожмет предмет и расслабит хватку, при этом серва будет удерживать текущее положение и не даст разжать захват. 

 

так что все что мне нужно это делать очень короткий шаг в обратную сторону, для расслабления.... 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

на руке датчиков дофига. и давления и температуры и так далее. и мозг знает насколько сжато. а твоя серва и ардуина нет

если для тебя линейный стабилизатор очень геморно поставить за 10 рублей с 3 выводами то дело твое

fagci
Offline
Зарегистрирован: 12.01.2015

Может для остановки использовать таймер на максимальное возможное время сжатия/разжатия?

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

а как ардуина узнает маленький или большой предмет сжимается? 

да и один и тот же предмет, тот же паравозик на фото, с разных сторон имеет разные габариты

хоть плавно хоть резко ардуина не узнает насколько сжато если ей напрямую не говорить. или с пульта управлять или ставить датчик

SLOM
Offline
Зарегистрирован: 06.11.2014

jeka_tm пишет:

на руке датчиков дофига. и давления и температуры и так далее. и мозг знает насколько сжато. а твоя серва и ардуина нет

если для тебя линейный стабилизатор очень геморно поставить за 10 рублей с 3 выводами то дело твое

 

в серве тоже есть "датчик" резистор, и мозги, которые отслеживают изменение положения и недают его менять. 

ардуине при этом ничего думать ненужно и знать тоже. ардуина послала команду, а дальше дело за сервой. 

 

так вот, беда ся в коде ардуино. сейчас при нажатии на кнопки ардуина посылает серве команду например повернуться на 90град. 

серва на 50град встретила предмет и сжала его. но поскольку цель, не достигнута, мы стоим на 50 а надо на 90, серва продолжает напрягать мотор, он грееться, просаживает ток всей системы и сам тоже горит, одну серву я уже убил.... 

если же после отпускания кнопки посылать короткую команду крутить в обратную сторону на 0,001 то визуально серва даже не сдвиниться, зто последнюю полученую команду она выполнит, перебив тем самым команду продолжать движение на 90 град, и спокойно, без напряга будет удерживать положение на 50. 

 

так понятно? 

вопрос, как это реализовать, чутье подсказывает что это достаточно просто, но поскольку я не программист, для меня это неподсилу (

SLOM
Offline
Зарегистрирован: 06.11.2014

fagci пишет:

Может для остановки использовать таймер на максимальное возможное время сжатия/разжатия?

 

а смысл? если можно послать последнюю команду, которая даст расслабление. 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

простой вопрос: сервой управляется в ручном режиме копнками пульта или просто команда сжать или разжать, а она уже должна сама подстроится?

SLOM
Offline
Зарегистрирован: 06.11.2014

jeka_tm пишет:

а как ардуина узнает маленький или большой предмет сжимается? 

да и один и тот же предмет, тот же паравозик на фото, с разных сторон имеет разные габариты

хоть плавно хоть резко ардуина не узнает насколько сжато если ей напрямую не говорить. или с пульта управлять или ставить датчик

 

ардуине ничего знать ненужно. 

человек зажимает кнопку, пока кнопка зажата, ардуина начинает суммировать дискретные значения поворота по 0,012

//Размер шага V_STEP и H_STEP побираем экспериментально для достижения нужной скорости поворота серв

const float V_STEP = 0.012; // Шаг - знаение отвечающее за скорость вращения по вертикали.
const float H_STEP = 0.012; // Шаг - знаение отвечающее за скорость вращения по горизонтали
 
и клешня закрываеться, и зажимает предмет, и при этом не останавливаеться! ведь человек еще держит кнопку, а градусы поворота все прибавляються и прибавляються, пока не дойдут до максимума. потом человек отпускает кнопку, но серва получивашая задание повернуться на 90, но застрявшая на 50-89 всеравно продалжает напрягаться. 
но если человек кратковременно, очень быстро нажмет кнопку обратного хода, то серва из текущего положения, получит команду -0,012 и сделает этот короткий шаг назад, глаз разницу не заметит, предмет тоже останеться зажатым. но серва задание выполнит не встретив помех и расслабиться, будет просто стоять на 49,988  
 
все просто. 
блин ребята вы же программисты, вам же это как 2 пальца, помогите просто с этой функцией, добавить обратный ход ))
SLOM
Offline
Зарегистрирован: 06.11.2014

jeka_tm пишет:

простой вопрос: сервой управляется в ручном режиме копнками пульта или просто команда сжать или разжать, а она уже должна сама подстроится?

 

человек жмет кнопки со смартфона, через блютус. на ардуину. 

 

fagci
Offline
Зарегистрирован: 12.01.2015

SLOM пишет:

а смысл? если можно послать последнюю команду, которая даст расслабление. 

Как раз вместо датчика сжатия. Посжимали 500мс например и хватит=)

И сжать успеет и сгореть не успеет=)

При чем таймер через http://arduino.cc/en/reference/millis

SLOM
Offline
Зарегистрирован: 06.11.2014

fagci пишет:

Как раз вместо датчика сжатия. Посжимали 500мс например и хватит=)

И сжать успеет и сгореть не успеет=)

 

и так тоже можно, но в любом случае, позжимать 500мс нужно после отпускания кнопки :) и ппотом расслабиться. 

так что по сути тоже самое что я предлагаю, разница в задержке. 

вопрос как это сделать? 

fagci
Offline
Зарегистрирован: 12.01.2015

типа если нажали, засекаем время и крутим луп, проверяем время затраченное, дошло до 500мс, прерываем сжатие

http://cxem.net/arduino/arduino5.php

Вообще, в системах, где критичен интервал между командами, нужно использовать конструкцию, как в примере по ссылке. delay() он хоть и делает задержку, но не все так просто. В ардуино одна проблема-приостанавливается работа всей программы. В программировании для ПК например возникает проблема неточной задержки, связанная с переключением между процессами, тогда после delay(1000) может поработать другое приложение, после чего через 200мс например только сработает остальной код.

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

а зачем тогда таймера и тп. аккуратнее кпоками нажимай и все. задержку между шагами чтобы быстро не двигалась и все)))

fagci
Offline
Зарегистрирован: 12.01.2015

защита от дурака всегда должна быть=)

SLOM
Offline
Зарегистрирован: 06.11.2014

jeka_tm пишет:

а зачем тогда таймера и тп. аккуратнее кпоками нажимай и все. задержку между шагами чтобы быстро не двигалась и все)))

 

у меня с этим проблем нет, я это понимаю и могу делать все аккуратно, но эта штука будет в руках у детей, и там то ей сразу писец прийдет )

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

а если дети ставь датчик))

спасешь серву

SLOM
Offline
Зарегистрирован: 06.11.2014

ох ну и программисты пошли))

нет чтоб пару сточек кода подсказать, так нет же разведут демагогии на 3 страницы :)

 

или все присутствующие как и я не программисты? :)

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

если ты знаешь способ как программно узнать размер объекта то не вопрос.

например ребенок нажал и не отпустил кнопку. программа если чуть назад вернет серву неплохо. только если слишком рано то объект не захватится, если поздно то уже серва может сдохнуть, и чуть назад вернуть не поможет

серва это испольнительный инструмент, ей сказали она делает, даже если сгорит от этого, она будет пытаться сделать то что ты сказал

я лично не представляю как программа может это компенсировать если программе неизвестен размер объекта или то что серва уже перегружена, она основе чего она должна решить что все стоп и чуть назад

как по мне ты или наивный или ленивый. без обид

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

хотя возможно ты хотел сделать следующее: повернуть серву пок ане упрется, а потом вернуть назад, то есть объект сам остановит серву, а в перегрузе она типа будет недолго. это имелось в виду?

но ты же не знаешь насколько вернутся назад. это не шаговый двигатель который крутился уперся и вернул на шаг. серве ты должен сказать не на сколько вернутся назад, она такого не понимает, а какой угол занять))

SLOM
Offline
Зарегистрирован: 06.11.2014

Жека, да вы правы если кнопку не отпускать долго то серва сгорит, но дети не будут так долго ее держать, кнопку будут нажимать только до тех пор пока серва не захватит обьект, а дальше кнопку отпустят, и вот тут нужно сделать микро возврат сервы на 1 шаг назад. 

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

и всего то делов :)

или вы как и я новичек и не знаете как это сделать? 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

я так тут поболтать прихожу. программировать не мое))

кстати на детей я бы не надеялся. они же могут просто не отпустить потому что просто интересно что крепче/сильнее. я бы точно проверил что будет)

SLOM
Offline
Зарегистрирован: 06.11.2014

jeka_tm пишет:

хотя возможно ты хотел сделать следующее: повернуть серву пок ане упрется, а потом вернуть назад, то есть объект сам остановит серву, а в перегрузе она типа будет недолго. это имелось в виду?

но ты же не знаешь насколько вернутся назад. это не шаговый двигатель который крутился уперся и вернул на шаг. серве ты должен сказать не на сколько вернутся назад, она такого не понимает, а какой угол занять))

 

просто 1 шаг назад, и все, ей не нужно знать на сколько куда возвращаться. просто последним что прийдет на серву это задание которое она может выполнить, тогда она его выполняет и не жрет ток, не горит. 

а захват предмета, это сейчас для нее задание которое она выполнить не может. 

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

а если она при отпускании кнопки получает команду шаг назад и стоп, то она выполняет задание и замерает. 

 

так понятно? 

SLOM
Offline
Зарегистрирован: 06.11.2014

jeka_tm пишет:

я так тут поболтать прихожу. программировать не мое))

 

я уже по аватарке понял :)

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

а если чуть передержать кнопку она вернется назад, но все равно будет перегружаться

короче одна надежда что ребенок вовремя отпустит. если нет ставь новую серву

бедные сервы. они еще не знают что их на смерть отправили потому что стабилизатор было лень поставить

fagci
Offline
Зарегистрирован: 12.01.2015

пробуйте сделать что-то типа этого:

unsigned long oldTime;
int buttonId=-1;

loop(){
if(кнопкаЗахватаНажата){
if(buttonId!=ид_кнопки_захвата){
buttonId=ид_кнопки_захвата;
oldTime=millis();
}
if(millis()-oldTime>500){
стопэ;
buttonId=-1;
}
}
}

Если кнопка нажата впервые, то засекаем момент времени и в цикле проверяем, держим ее же и пора ли отпускать..так же и для отпускания

SLOM
Offline
Зарегистрирован: 06.11.2014

fagci спасибо что откликнулись, но чтото не получилось вставить в код, ругаеться на ошибки, одни вроде устраняю, другие вылезают. 

if(btca2aLite.Button(KEYCODE_BUTTON_A)){

if(buttonId!=0){
buttonId=0;
oldTime=millis();
}
if(millis()-oldTime>500){
moveServoHRight = false;;
buttonId=-1;
}
SLOM
Offline
Зарегистрирован: 06.11.2014

ругаеться на первую скобку 

void performServo()
{
    //Установлен флаг движения вверх и текущий угол не максимальный
    if (moveServoVUp && curVAngle + V_STEP <= V_U_ANGLE)
    {
        //К текущему верт. углу прибавляем шаг
        curVAngle += V_STEP;
    }
    //Установлен флаг движения вниз и текущий угол не минимален
    else if (moveServoVDown && curVAngle - V_STEP >= V_D_ANGLE)
    {
        //От текущего верт. угла отнимаем шаг
        curVAngle -= V_STEP;
    }
    //Установлен флаг движения влево и текущий угол не максимален
    if (moveServoHLeft && curHAngle + H_STEP <= H_L_ANGLE)
    {
        //К текущему гор. углу прибавляем гор. шаг
        curHAngle += H_STEP;
    }
    //Установлен флаг движения вправо и текущий угол не минимален
    else if (moveServoHRight && curHAngle - H_STEP >= H_R_ANGLE)
    {
        //От текущего угла отнимаем гор. шаг
        curHAngle -= H_STEP;
    }
    
    //Если было движние по вертикали
    if (moveServoVUp || moveServoVDown)
    {
        myservoV.write(curVAngle);
    }
    //Если было движение по горизонтали
    if (moveServoHLeft || moveServoHRight)
    {
        myservoH.write(curHAngle);
    }
}
fagci
Offline
Зарегистрирован: 12.01.2015
if(btca2aLite.Button(KEYCODE_BUTTON_A)){

if(buttonId!=KEYCODE_BUTTON_A){
buttonId=KEYCODE_BUTTON_A;
oldTime=millis();
}
if(millis()-oldTime>500){
moveServoHRight = false;;
buttonId=-1;
}

 

SLOM
Offline
Зарегистрирован: 06.11.2014

всеравно на туже скобку ругаеться

 

void performServo()
{
SLOM
Offline
Зарегистрирован: 06.11.2014

ага добавил еще одну скобку, откомпилило, сейчас зпбью другие кнопки и залью в машину)

 

fagci
Offline
Зарегистрирован: 12.01.2015

У Вас машинка какой препарат возит? ЛСД?=)

для детей самое то, пушку еще приделать, чтобы инъекции делать тем, кто боится и кого не догнать=)

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

а ты название темы прочитай)))

SLOM
Offline
Зарегистрирован: 06.11.2014

вставил такой код

if(btca2aLite.Button(KEYCODE_BUTTON_A)){

if(buttonId!=KEYCODE_BUTTON_A){
buttonId=KEYCODE_BUTTON_A;
oldTime=millis();
}
if(millis()-oldTime>500){
moveServoHRight = false;;
buttonId=-1;
}   


if(btca2aLite.Button(KEYCODE_BUTTON_Y)){

if(buttonId!=KEYCODE_BUTTON_Y){
buttonId=KEYCODE_BUTTON_Y;
oldTime=millis();
}
if(millis()-oldTime>500){
moveServoHRight = false;;
buttonId=-1;
}   
}     

 

неработаю, на кнопки не реагируют

SLOM
Offline
Зарегистрирован: 06.11.2014

fagci пишет:

У Вас машинка какой препарат возит? ЛСД?=)

для детей самое то, пушку еще приделать, чтобы инъекции делать тем, кто боится и кого не догнать=)

 

нам спиртное никчему я отвечу почему :)

 

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

https://www.youtube.com/watch?v=zSKRCsBswvI

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

сначала серву расслабить. потом колеса, шасси, захват уже накакой будет. а машинки с глазами будут водить хороводы

SLOM
Offline
Зарегистрирован: 06.11.2014

не ну пАцанЫ, реально дайте серву расслабить :)

fagci
Offline
Зарегистрирован: 12.01.2015
if(btca2aLite.Button(KEYCODE_BUTTON_A)){
	if(buttonId!=KEYCODE_BUTTON_A){
		buttonId=KEYCODE_BUTTON_A;
		oldTime=millis();
	}
	if(millis()-oldTime>500){
		moveServoHRight = false;;
		buttonId=-1;
	}   
}

if(btca2aLite.Button(KEYCODE_BUTTON_Y)){
	if(buttonId!=KEYCODE_BUTTON_Y){
		buttonId=KEYCODE_BUTTON_Y;
		oldTime=millis();
	}
	if(millis()-oldTime>500){
		moveServoHRight = false;;
		buttonId=-1;
	}   
}     

Вот так скобки должны быть=)

Ту которую ставили - убрать надо=)

SLOM
Offline
Зарегистрирован: 06.11.2014

стало ругаться на строчку 

    if (btca2aLite.ButtonReleased(KEYCODE_DPAD_UP) && btca2aLite.ButtonReleased(KEYCODE_DPAD_DOWN) && btca2aLite.ButtonReleased(KEYCODE_DPAD_LEFT) && btca2aLite.ButtonReleased(KEYCODE_DPAD_RIGHT)){

 

 

fagci
Offline
Зарегистрирован: 12.01.2015

Надо весь код тогда=)

SLOM
Offline
Зарегистрирован: 06.11.2014

выкладываю целеком:

 

// Скетч для управления через блютус, Wild Thumper 6WD, на ардуино совместимом контролере TREX controller. реализовано движение и управление клешней. 


#include <BTCA2ALite.h>// Добавляем библиотеку блютус программы
#include <Servo.h> // Добавляем библиотеку серво

Servo myservoH; // Горизонтальная серва углы от 0 до 180 (центровка 89)
Servo myservoV; // Вертикальная серва углы от 1 до 45
const int H_SERVO_PIN = 5; // Горизонтальная серва подключена к пину 7
const int V_SERVO_PIN = 8; //Пин вертикального сервопривода 8
const float H_L_ANGLE = 116; // Максимальные угл поворота башни налево
const float H_R_ANGLE = 45; // Максимальные угл поворота башни направо
const float H_DEF_ANGLE = 38; // Дефолтный угол (центровка)
const float V_U_ANGLE = 120; // Максимальные угл поворота башни вверх
const float V_D_ANGLE = 0; // Максимальные угл поворота башни вниз
const float V_DEF_ANGLE = 90; // Дефолтный угол (центровка)
//Размер шага V_STEP и H_STEP побираем экспериментально для достижения нужной скорости поворота серв
const float V_STEP = 0.012; // Шаг - знаение отвечающее за скорость вращения по вертикали.
const float H_STEP = 0.012; // Шаг - знаение отвечающее за скорость вращения по горизонтали
float curVAngle = V_DEF_ANGLE; //Переменная текущего угла верт. сервы
float curHAngle = H_DEF_ANGLE; //Переменная текущего угла гор. сервы
bool moveServoVUp = false; //Флаг движения верт. сервы вверх
bool moveServoVDown = false; //Флаг движения верт. сервы вниз
bool moveServoHLeft = false; //Флаг движения гор. сервы влево
bool moveServoHRight = false; //Флаг движения гор. сервы вправо

btca2aLite btca2aLite; // Конструктор btca2aLite


// задаем пины для левого мотора
#define Dir_L 2
#define Pwm_L 3
#define Brake_L 4
// задаем пины для правого мотора
#define Dir_R 10
#define Pwm_R 11
#define Brake_R 9

// Задаем скорости для движения
byte MaxSpeed = 250; // Максимальная скорость
byte MinSpeed = 100;  // Минимальная скорость

int forw_back = 0;
int righ_left = 0;

byte step_fb = 5;     // Шаг изменения скорости движения вперед - назад
byte step_stop = 10;  // Шаг изменения скорости остановки
byte step_rl =  20;    // Шаг изменения скорости движения вправо - влево
byte step_dir = 10;   // Шаг изменения скорости выравнивания

// Задаем время работы сервы
unsigned long oldTime;
int buttonId=0;


#define SHOT  12 // пин для водомета

enum States
{
    WAITING,
    READING,
    RUNNING,
    ERROR,
    TIMEOUT
};

States state;
States onWait();
States onRead();
States onRun();
States onError();

States onTimeout();

void performServo(); // добовляем сервы


void setup(){
    Serial.begin(9600); // Скорость BT и порта должна быть 9600
    //Моторы
    pinMode (Pwm_L, OUTPUT);
    pinMode (Dir_L, OUTPUT);
    pinMode (Brake_L, OUTPUT);
    
    pinMode (Pwm_R, OUTPUT);
    pinMode (Dir_R, OUTPUT);
    pinMode (Brake_R, OUTPUT);
    
    digitalWrite (Pwm_L, LOW);
    digitalWrite (Pwm_R, LOW);
    
    digitalWrite (Brake_L, LOW);
    digitalWrite (Brake_R, LOW);
  
 pinMode(SHOT, OUTPUT); // задаем выход для стрельбы водой
    
    // устанавливаем пин как вывод управления сервой
    myservoH.attach(H_SERVO_PIN);
    myservoV.attach(V_SERVO_PIN);
    myservoH.write(curHAngle);
    myservoV.write(curVAngle);
    
    
    //Светодиод
    pinMode(13, OUTPUT); // Инициализируем пин светодиода
    digitalWrite(13, HIGH); // Светодиод выключен
}

void loop(){
    
    btca2aLite.ReadCommand(); // Считывание принятых команд (кодов кнопок)
    //Вызываем функцию управление сервами
    performServo();
    

  static unsigned long pre_millis = 0;
  if(millis()-pre_millis > 50)
  {
    pre_millis = millis();
    
    if(btca2aLite.ButtonPressed(KEYCODE_DPAD_UP)) 
    {
      forw_back += step_fb;
      if(forw_back > 0 && forw_back < MinSpeed) forw_back = MinSpeed;
    }
    else if(btca2aLite.ButtonPressed(KEYCODE_DPAD_DOWN)) 
    {
      forw_back -= step_fb;
      if(forw_back < 0 && forw_back > MinSpeed*-1) forw_back = MinSpeed*-1;
    }
    else 
    {
      if(forw_back < 0) forw_back += step_stop;
      else if(forw_back > 0) forw_back -= step_stop;
      if(abs(forw_back) < MinSpeed) forw_back = 0;
    }
    forw_back = constrain(forw_back, MaxSpeed*-1, MaxSpeed);


    if(btca2aLite.ButtonPressed(KEYCODE_DPAD_RIGHT)) 
    {
      righ_left += step_rl;
      if(righ_left > 0 && righ_left < MinSpeed) righ_left = MinSpeed;
    }
    else if(btca2aLite.ButtonPressed(KEYCODE_DPAD_LEFT)) 
    {
      righ_left -= step_rl;
      if(righ_left < 0 && righ_left > MinSpeed*-1) righ_left = MinSpeed*-1;
    }
    else 
    {
      if(righ_left < 0) righ_left += step_dir;
      else if(righ_left > 0) righ_left -= step_dir;
      if(abs(righ_left) < MinSpeed) righ_left = 0;
    }
    righ_left = constrain(righ_left, MaxSpeed*-1, MaxSpeed);


    int pwm_l = forw_back + righ_left;
    int pwm_r = forw_back - righ_left;
    pwm_l = constrain(pwm_l, MaxSpeed*-1, MaxSpeed);
    pwm_r = constrain(pwm_r, MaxSpeed*-1, MaxSpeed);

    digitalWrite(Dir_L, (pwm_l<0)?0:1);
    digitalWrite(Dir_R, (pwm_r<0)?0:1);
    analogWrite(Pwm_L, abs(pwm_l));
    analogWrite(Pwm_R, abs(pwm_r));
  }
        
  
    
    //-------— включение насоса —-------------
   if (btca2aLite.ButtonPressed(KEYCODE_BUTTON_SELECT))
    { 
     digitalWrite (SHOT, HIGH);
     }
    //-------— выключение насоса происходит автоматически после отпускания кнопки—------------- 
   if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_SELECT))
    {
   digitalWrite (SHOT, LOW);
    } 
    
    
    //--------— Повороты серв при нажатии кнопок —-------------
    
    
if(btca2aLite.Button(KEYCODE_BUTTON_A)){
	if(buttonId!=KEYCODE_BUTTON_A){
		buttonId=KEYCODE_BUTTON_A;
		oldTime=millis();
	}
	if(millis()-oldTime>500){
		moveServoHRight = false;;
		buttonId=-1;
	}   
}

if(btca2aLite.Button(KEYCODE_BUTTON_Y)){
	if(buttonId!=KEYCODE_BUTTON_Y){
		buttonId=KEYCODE_BUTTON_Y;
		oldTime=millis();
	}
	if(millis()-oldTime>500){
		moveServoHRight = false;;
		buttonId=-1;
	}   
}     
    
    
    if(btca2aLite.Button(KEYCODE_BUTTON_X)) // servoV вниз
    {
        moveServoVDown = true;
              
   

    }
    if(btca2aLite.Button(KEYCODE_BUTTON_B)) // servoV вверх
    {
        moveServoVUp = true;
              
    }

    
//--------— чтобы сервы не продолжали движения при отжатых кнопках —-------------    
if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_X))
{
moveServoVDown = false;
}
if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_B))
{
moveServoVUp = false;
}

if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_A))
{
moveServoHRight = false;
}
if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_Y))
{
moveServoHLeft = false;
}
 }   
    
    //----------------— Стоп —---------------------
    
    // Если не нажата ни одна кнопка курсора происходит остановка, скорость 0 для каждого мотора
    if (btca2aLite.ButtonReleased(KEYCODE_DPAD_UP) && btca2aLite.ButtonReleased(KEYCODE_DPAD_DOWN) && btca2aLite.ButtonReleased(KEYCODE_DPAD_LEFT) && btca2aLite.ButtonReleased(KEYCODE_DPAD_RIGHT)){
        analogWrite (Pwm_L, 0);
        analogWrite (Pwm_R, 0);
    }
}


//Функция управления сервоприводами (вызывается в теле loop на каждой итерации)
//Выполняет изменения положения серв на подобранный шаг согласно установленным флагам движения
//Флаги устанавливаются согласно поступившим символам управления сервами
void performServo()
{
    //Установлен флаг движения вверх и текущий угол не максимальный
    if (moveServoVUp && curVAngle + V_STEP <= V_U_ANGLE)
    {
        //К текущему верт. углу прибавляем шаг
        curVAngle += V_STEP;
    }
    //Установлен флаг движения вниз и текущий угол не минимален
    else if (moveServoVDown && curVAngle - V_STEP >= V_D_ANGLE)
    {
        //От текущего верт. угла отнимаем шаг
        curVAngle -= V_STEP;
    }
    //Установлен флаг движения влево и текущий угол не максимален
    if (moveServoHLeft && curHAngle + H_STEP <= H_L_ANGLE)
    {
        //К текущему гор. углу прибавляем гор. шаг
        curHAngle += H_STEP;
    }
    //Установлен флаг движения вправо и текущий угол не минимален
    else if (moveServoHRight && curHAngle - H_STEP >= H_R_ANGLE)
    {
        //От текущего угла отнимаем гор. шаг
        curHAngle -= H_STEP;
    }
    
    //Если было движние по вертикали
    if (moveServoVUp || moveServoVDown)
    {
        myservoV.write(curVAngle);
    }
    //Если было движение по горизонтали
    if (moveServoHLeft || moveServoHRight)
    {
        myservoH.write(curHAngle);
    }
}

 

SLOM
Offline
Зарегистрирован: 06.11.2014

сервы раньше водометом управляли, пока водомет убрал, поставил клешню, потом буду водомет ставить, в задней части :)

fagci
Offline
Зарегистрирован: 12.01.2015

Как-то так:

// Скетч для управления через блютус, Wild Thumper 6WD, на ардуино совместимом контролере TREX controller. реализовано движение и управление клешней. 


#include <BTCA2ALite.h>// Добавляем библиотеку блютус программы
#include <Servo.h> // Добавляем библиотеку серво

Servo myservoH; // Горизонтальная серва углы от 0 до 180 (центровка 89)
Servo myservoV; // Вертикальная серва углы от 1 до 45
const int H_SERVO_PIN = 5; // Горизонтальная серва подключена к пину 7
const int V_SERVO_PIN = 8; //Пин вертикального сервопривода 8
const float H_L_ANGLE = 116; // Максимальные угл поворота башни налево
const float H_R_ANGLE = 45; // Максимальные угл поворота башни направо
const float H_DEF_ANGLE = 38; // Дефолтный угол (центровка)
const float V_U_ANGLE = 120; // Максимальные угл поворота башни вверх
const float V_D_ANGLE = 0; // Максимальные угл поворота башни вниз
const float V_DEF_ANGLE = 90; // Дефолтный угол (центровка)
//Размер шага V_STEP и H_STEP побираем экспериментально для достижения нужной скорости поворота серв
const float V_STEP = 0.012; // Шаг - знаение отвечающее за скорость вращения по вертикали.
const float H_STEP = 0.012; // Шаг - знаение отвечающее за скорость вращения по горизонтали
float curVAngle = V_DEF_ANGLE; //Переменная текущего угла верт. сервы
float curHAngle = H_DEF_ANGLE; //Переменная текущего угла гор. сервы
bool moveServoVUp = false; //Флаг движения верт. сервы вверх
bool moveServoVDown = false; //Флаг движения верт. сервы вниз
bool moveServoHLeft = false; //Флаг движения гор. сервы влево
bool moveServoHRight = false; //Флаг движения гор. сервы вправо

btca2aLite btca2aLite; // Конструктор btca2aLite


// задаем пины для левого мотора
#define Dir_L 2
#define Pwm_L 3
#define Brake_L 4
// задаем пины для правого мотора
#define Dir_R 10
#define Pwm_R 11
#define Brake_R 9

// Задаем скорости для движения
byte MaxSpeed = 250; // Максимальная скорость
byte MinSpeed = 100;  // Минимальная скорость

int forw_back = 0;
int righ_left = 0;

byte step_fb = 5;     // Шаг изменения скорости движения вперед - назад
byte step_stop = 10;  // Шаг изменения скорости остановки
byte step_rl =  20;    // Шаг изменения скорости движения вправо - влево
byte step_dir = 10;   // Шаг изменения скорости выравнивания

// Задаем время работы сервы
unsigned long oldTime;
int buttonId=0;


#define SHOT  12 // пин для водомета

enum States
{
    WAITING,
    READING,
    RUNNING,
    ERROR,
    TIMEOUT
};

States state;
States onWait();
States onRead();
States onRun();
States onError();

States onTimeout();

void performServo(); // добовляем сервы


void setup(){
    Serial.begin(9600); // Скорость BT и порта должна быть 9600
    //Моторы
    pinMode (Pwm_L, OUTPUT);
    pinMode (Dir_L, OUTPUT);
    pinMode (Brake_L, OUTPUT);
    
    pinMode (Pwm_R, OUTPUT);
    pinMode (Dir_R, OUTPUT);
    pinMode (Brake_R, OUTPUT);
    
    digitalWrite (Pwm_L, LOW);
    digitalWrite (Pwm_R, LOW);
    
    digitalWrite (Brake_L, LOW);
    digitalWrite (Brake_R, LOW);
  
 pinMode(SHOT, OUTPUT); // задаем выход для стрельбы водой
    
    // устанавливаем пин как вывод управления сервой
    myservoH.attach(H_SERVO_PIN);
    myservoV.attach(V_SERVO_PIN);
    myservoH.write(curHAngle);
    myservoV.write(curVAngle);
    
    
    //Светодиод
    pinMode(13, OUTPUT); // Инициализируем пин светодиода
    digitalWrite(13, HIGH); // Светодиод выключен
}

void loop(){
    
    btca2aLite.ReadCommand(); // Считывание принятых команд (кодов кнопок)
    //Вызываем функцию управление сервами
    performServo();
    

  static unsigned long pre_millis = 0;
  if(millis()-pre_millis > 50)
  {
    pre_millis = millis();
    
    if(btca2aLite.ButtonPressed(KEYCODE_DPAD_UP)) 
    {
      forw_back += step_fb;
      if(forw_back > 0 && forw_back < MinSpeed) forw_back = MinSpeed;
    }
    else if(btca2aLite.ButtonPressed(KEYCODE_DPAD_DOWN)) 
    {
      forw_back -= step_fb;
      if(forw_back < 0 && forw_back > MinSpeed*-1) forw_back = MinSpeed*-1;
    }
    else 
    {
      if(forw_back < 0) forw_back += step_stop;
      else if(forw_back > 0) forw_back -= step_stop;
      if(abs(forw_back) < MinSpeed) forw_back = 0;
    }
    forw_back = constrain(forw_back, MaxSpeed*-1, MaxSpeed);


    if(btca2aLite.ButtonPressed(KEYCODE_DPAD_RIGHT)) 
    {
      righ_left += step_rl;
      if(righ_left > 0 && righ_left < MinSpeed) righ_left = MinSpeed;
    }
    else if(btca2aLite.ButtonPressed(KEYCODE_DPAD_LEFT)) 
    {
      righ_left -= step_rl;
      if(righ_left < 0 && righ_left > MinSpeed*-1) righ_left = MinSpeed*-1;
    }
    else 
    {
      if(righ_left < 0) righ_left += step_dir;
      else if(righ_left > 0) righ_left -= step_dir;
      if(abs(righ_left) < MinSpeed) righ_left = 0;
    }
    righ_left = constrain(righ_left, MaxSpeed*-1, MaxSpeed);


    int pwm_l = forw_back + righ_left;
    int pwm_r = forw_back - righ_left;
    pwm_l = constrain(pwm_l, MaxSpeed*-1, MaxSpeed);
    pwm_r = constrain(pwm_r, MaxSpeed*-1, MaxSpeed);

    digitalWrite(Dir_L, (pwm_l<0)?0:1);
    digitalWrite(Dir_R, (pwm_r<0)?0:1);
    analogWrite(Pwm_L, abs(pwm_l));
    analogWrite(Pwm_R, abs(pwm_r));
  }
        
  
    
    //-------— включение насоса —-------------
   if (btca2aLite.ButtonPressed(KEYCODE_BUTTON_SELECT))
    { 
     digitalWrite (SHOT, HIGH);
     }
    //-------— выключение насоса происходит автоматически после отпускания кнопки—------------- 
   if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_SELECT))
    {
   digitalWrite (SHOT, LOW);
    } 
    
    
    //--------— Повороты серв при нажатии кнопок —-------------
    
    
if(btca2aLite.Button(KEYCODE_BUTTON_A)){
	if(buttonId!=KEYCODE_BUTTON_A){
		buttonId=KEYCODE_BUTTON_A;
		oldTime=millis();
	}
	if(millis()-oldTime>500){
		moveServoHRight = false;;
		buttonId=-1;
	}   
}

if(btca2aLite.Button(KEYCODE_BUTTON_Y)){
	if(buttonId!=KEYCODE_BUTTON_Y){
		buttonId=KEYCODE_BUTTON_Y;
		oldTime=millis();
	}
	if(millis()-oldTime>500){
		moveServoHRight = false;;
		buttonId=-1;
	}   
}     
    
    
    if(btca2aLite.Button(KEYCODE_BUTTON_X)) // servoV вниз
    {
        moveServoVDown = true;
              
   

    }
    if(btca2aLite.Button(KEYCODE_BUTTON_B)) // servoV вверх
    {
        moveServoVUp = true;
              
    }

    
//--------— чтобы сервы не продолжали движения при отжатых кнопках —-------------    
if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_X))
{
moveServoVDown = false;
}
if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_B))
{
moveServoVUp = false;
}

if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_A))
{
moveServoHRight = false;
}
if(btca2aLite.ButtonReleased(KEYCODE_BUTTON_Y))
{
moveServoHLeft = false;
}
 
    
    //----------------— Стоп —---------------------
    
    // Если не нажата ни одна кнопка курсора происходит остановка, скорость 0 для каждого мотора
    if (btca2aLite.ButtonReleased(KEYCODE_DPAD_UP) && btca2aLite.ButtonReleased(KEYCODE_DPAD_DOWN) && btca2aLite.ButtonReleased(KEYCODE_DPAD_LEFT) && btca2aLite.ButtonReleased(KEYCODE_DPAD_RIGHT)){
        analogWrite (Pwm_L, 0);
        analogWrite (Pwm_R, 0);
    }
}


//Функция управления сервоприводами (вызывается в теле loop на каждой итерации)
//Выполняет изменения положения серв на подобранный шаг согласно установленным флагам движения
//Флаги устанавливаются согласно поступившим символам управления сервами
void performServo()
{
    //Установлен флаг движения вверх и текущий угол не максимальный
    if (moveServoVUp && curVAngle + V_STEP <= V_U_ANGLE)
    {
        //К текущему верт. углу прибавляем шаг
        curVAngle += V_STEP;
    }
    //Установлен флаг движения вниз и текущий угол не минимален
    else if (moveServoVDown && curVAngle - V_STEP >= V_D_ANGLE)
    {
        //От текущего верт. угла отнимаем шаг
        curVAngle -= V_STEP;
    }
    //Установлен флаг движения влево и текущий угол не максимален
    if (moveServoHLeft && curHAngle + H_STEP <= H_L_ANGLE)
    {
        //К текущему гор. углу прибавляем гор. шаг
        curHAngle += H_STEP;
    }
    //Установлен флаг движения вправо и текущий угол не минимален
    else if (moveServoHRight && curHAngle - H_STEP >= H_R_ANGLE)
    {
        //От текущего угла отнимаем гор. шаг
        curHAngle -= H_STEP;
    }
    
    //Если было движние по вертикали
    if (moveServoVUp || moveServoVDown)
    {
        myservoV.write(curVAngle);
    }
    //Если было движение по горизонтали
    if (moveServoHLeft || moveServoHRight)
    {
        myservoH.write(curHAngle);
    }
}

Вообще этот код бы почистить, сдается мне, что можно сделать проще=)..но к концу рабочего дня не думается=)

SLOM
Offline
Зарегистрирован: 06.11.2014

нереагирует на нажатие кнопок, может if(buttonId!=KEYCODE_BUTTON_A){  надо не название кнопки а цифру 0, 1, 2.....100 ))?

SLOM
Offline
Зарегистрирован: 06.11.2014

fagci пишет:

обще этот код бы почистить, сдается мне, что можно сделать проще=)..но к концу рабочего дня не думается=)

 

да главное чтоб работал :)

он весит всего 6,7.... а залить можно 30 :)

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

видео забавное

fagci
Offline
Зарегистрирован: 12.01.2015

А тут кстати вес не пропорционально зависит от объема кода, оптимизация, все дела=)

Щас еще посмотрю, что не так=)..попорчу код маленько=)

SLOM
Offline
Зарегистрирован: 06.11.2014

fagci пишет:

А тут кстати вес не пропорционально зависит от объема кода, оптимизация, все дела=)

Щас еще посмотрю, что не так=)..попорчу код маленько=)

 

оптимизация это хорошо, но не в моих руках:)

спасибо за помощь, если вам вдруг нужна будет помощь по 3д обращайтесь:)

fagci
Offline
Зарегистрирован: 12.01.2015

Получается, что у Вас сейчас сервы останавливаются когда они уже стоят=)

if(btca2aLite.Button(KEYCODE_BUTTON_A)){
	if(buttonId!=KEYCODE_BUTTON_A){
		buttonId=KEYCODE_BUTTON_A;
		oldTime=millis();
	}
	if(millis()-oldTime>500){
		moveServoHRight = false;
		buttonId=-1;
	} else {
		moveServoHRight = true;
	}
}

if(btca2aLite.Button(KEYCODE_BUTTON_Y)){
	if(buttonId!=KEYCODE_BUTTON_Y){
		buttonId=KEYCODE_BUTTON_Y;
		oldTime=millis();
	}
	if(millis()-oldTime>500){
		moveServoHLeft = false;
		buttonId=-1;
	}   else {
		moveServoHLeft = true;
	}
}     

Вот теперь будут шевелиться, пока время не вышло=)

SLOM
Offline
Зарегистрирован: 06.11.2014

работает, серва движиться, но после зажима предмета и отпускания кнопки, как и раньше продолжает попытку сжиматься дальше, поидее время ожидания пол секунды? ждил с пол минуты, ничего.. ((