Смещение диапазона джойстика

virf
Offline
Зарегистрирован: 16.03.2016

Помогите разобраться (а то уже мозги потекли)

Суть вопроса - имеется джойстик и триммер подстройки (подстрочный резистор), по какой формуле считать?

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

Получается нужно смещать (триммировать) центральное положение джойстика, при этом крайними положениями стика по прежнему должны оставаться значения 0 и 1023.

Jatixo
Offline
Зарегистрирован: 13.01.2016

(1023-0)/2=511,5~=512

virf
Offline
Зарегистрирован: 16.03.2016

В смысле так? (joystick-trimmer)/2

По такой формуле получается что если триммер в крайнем положении
то диапазон джойстика от 0 до 512 (или от 0 до -512 если триммер в противоположном положении)

а когда триммер в центре то диапазон от -255 до 255

Получается потом обрезать от -255 до 255 с помощью constrain? и переводить уже с помощью map в необходимый мне диапазон?

P.S. Что то у меня аж воображение отключилось от кучи разных формул.
Надо наверно собрать стенд и смотреть как это на железе фурычит.

 

Logik
Offline
Зарегистрирован: 05.08.2014

Хммм... когда получил джойстик, подключил, посмотрел, что выдает, получил значение около 490. Это и стал вычитать из входящего. Соответственно по центру - 0, нормально. Поигрался и понял, что снимать с него сотни положений безсмыслено, рукой не установиш. Соответствено он был загрублен до 7 позиций в каждую сторону и вопрос его крайних значений снялся не возникнув ;)

Jatixo
Offline
Зарегистрирован: 13.01.2016

virf пишет:

В смысле так? (joystick-trimmer)/2

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

Jatixo
Offline
Зарегистрирован: 13.01.2016

Или у Вас допустим в центре 450, в крайних положениях 100 и 900, Вам надо все это привести к 0-1023? А смысл, это же будет растягивание, но лишних позиций не прибавится.

Если очень хочется, то резистор не нужен, можно типа такого:
 



if(joystick < 450)
	joystick = map(100, 449, 0, 511);
else
	joystick = map(450, 900, 512, 1023);

Если у Вас в крайних 0-1023, то:

if(joystick < 450)
	joystick = map(0, 449, 0, 511);
else
	joystick = map(450, 1023, 512, 1023);

 

virf
Offline
Зарегистрирован: 16.03.2016

Jatixo пишет:
Вы написали есть подстроечный резистор, я думал Вам надо выставить середину по аналоговым показаниям, вот и сказал, чтобы считывать показания, крутить и выставить 512. Напишите, понятнее, что Вам надо?

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

virf
Offline
Зарегистрирован: 16.03.2016

Jatixo пишет:

Если очень хочется, то резистор не нужен, можно типа такого:

Я наверно неправильно выразился и вы меня неправильно поняли,
нужно не просто избавиться от погрешности показаний джойстика (выставив в центр в 511 - 512)

а именно иметь возможность выставлять этот центр с помощью подстрочника.

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

Тот же пример с машиной: серва управляет поворотом колес, и если машину уводит в какую то сторону - прям на скорости с помощью подстрочника выставляем так что бы ехала прямо.

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

Jatixo
Offline
Зарегистрирован: 13.01.2016

Допустим у Вас машинка с сервоприводом 0-180 градусов, 90 прямо. Джойстик 512 по центру, резистор 512 по центру.
Значит как-то так: servo = map(joystick+trimmer-512, 0, 1023, 0, 180);
Если слишком резко резистор будет менять, то можно сделать вложенный map для trimmer, как-то так: servo = map(joystick+map(trimmer, 0, 1023, 0, 500)-250, 0, 1023, 0, 180); или просто servo = map(joystick+trimmer/2-256, 0, 1023, 0, 180);

Или вообще: servo = (joystick+trimmer/2-256)/5.6833;

virf
Offline
Зарегистрирован: 16.03.2016

При таком servo = map(joystick+map(trimmer, 0, 1023, 0, 500)-250, 0, 1023, 0, 180);

и таком варианте servo = (joystick+trimmer/2-256)/5.6833;

Когда "trimmer"  в центре все ок, когда  в крайнем положении выходит servo в диапазоне от -44 до 136, в противоположном положении от  44 до 224

А так servo = map(joystick+trimmer-512, 0, 1023, 0, 180);  "trimmer" в центре опять же все ок, а в крайних положениях  -90 90 и 90 269

Я в обще изначально думал про такую формулу (joystick+trimmer)/2 и в принципе все норм
servo = (joystick+trimmer)/2;
servo = constrain(servo, 256, 768);
servo = map(servo, 256, 768, 0, 180);

Но что я в обще начал всю эту волокиту - в идеале формула должна смещать значение центрального положения джойстика в зависимости от показаний подстрочника но при этом крайние положения джойстика всегда остаются 0 и 180

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

Jatixo
Offline
Зарегистрирован: 13.01.2016

Да, извините, не учел. Получается, все смещается, только центр правильно. Значит так:

angle = map(trigger, 0, 1023, 0, 180);

if(joystick < 512)
	servo = map(joystick, 0, 511, 0, angle);
else
	servo = map(joystick, 512, 1023, angle, 180);

Правда и 511, и 512 будет 90 градусов, ну зато центр стабильнее =)

Jatixo
Offline
Зарегистрирован: 13.01.2016

Только еще при включении надо считывать центр джойстика, авто калибровка, только пользователь не должен трогать его при включении. То есть считали center например 450, и там в коде уже использовать вместо 512 и 511 тоже без -1, тогда и центр будет правильнее вроде.

Jatixo
Offline
Зарегистрирован: 13.01.2016

Выше я описал, как я думаю, обычно делается, например колесо спустило у машинки, или квадрокоптер повредился, то не джойстика центр смещается, а серва делает поворот центра уже не 90 допустим, а 92, или квадрокоптера винты правые крутятся сильнее, а джойстик все там же по центру.

Но если Вам нужно именно джойстик регулировать без автокалибровки при включеннии, а резистором, то вот:

offset = 1023 - trigger;

if(joystick < offset)
	servo = map(joystick, 0, offset, 0, 89);
else
	servo = map(joystick, offset, 1023, 90, 180);

 

virf
Offline
Зарегистрирован: 16.03.2016

Jatixo пишет:
Значит так: angle = map(trigger, 0, 1023, 0, 180); if(joystick < 512) servo = map(joystick, 0, 511, 0, angle); else servo = map(joystick, 512, 1023, angle, 180); Правда и 511, и 512 будет 90 градусов, ну зато центр стабильнее =)

Проверил в роди все замечательно, огромное спасибо.
Слияние 511 и 512 думаю ощущаться не будет.

Jatixo пишет:
Но если Вам нужно именно джойстик регулировать без автокалибровки при включеннии, а резистором, то вот:

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

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

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

Jatixo
Offline
Зарегистрирован: 13.01.2016

virf пишет:

 

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

 

А если одна прошивка под несколько пультов, то в каждом править прошивку?
А если пользователь потом решит перепаять джойстик в пульте и там другой центр?
Да и все равно может сместиться центр на пару делений, но все же...

Правда вот этот резистор и поможет, хотя и делался совсем для другого, например если центр джойстика 100 из 0-1023, то триммера этого кода уже не хватит, а вот второго кода хватит, хоть центр 0 или 1023 будет =)

virf
Offline
Зарегистрирован: 16.03.2016

Jatixo пишет:
например если центр джойстика 100 из 0-1023, то триммера этого кода уже не хватит, а вот второго кода хватит, хоть центр 0 или 1023 будет =)

ну 100 это наверно перебор, в хороших (дорогих) джойстиках погрешность центра обычно +/- 10, в более дешевых соответственно не сильно качественных доходит до +/-50

с большей погрешностью мне встречались джойстики отслужившие более 5ти лет (резистивный слой резистора уже изношен) но все равно центр не уводит больше +/-100

второго это этого?

offset = 1023 - trigger;

if(joystick < offset)
	servo = map(joystick, 0, offset, 0, 89);
else
	servo = map(joystick, offset, 1023, 90, 180);

но она опять смещает диапазон

Jatixo
Offline
Зарегистрирован: 13.01.2016

Первый код правильнее, второй именно регулировка центра джойстика, а не сервы. Разве смещает, это при каких параметрах?

virf
Offline
Зарегистрирован: 16.03.2016

Опять получается в крайнем положении подстрочника джойстик работает в диапазоне  90 и 180 
(и подстрочник в противоположном положении - значения 0 и 90)

Причем как то рывком,  кручу подстрочник - до определенного момента диапазон на выходе как положено 0 - 180 и потом оп и сразу переключается в диапазон 0-90 (или соответственно 90-180 )

vdm
vdm аватар
Offline
Зарегистрирован: 29.08.2016

чтоб не писать новую тему, подниму эту из анналов истории :)

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

Считываю показания, и передаю на серву. Для перевода считанных показаний в градусы сервы использую функцию map.

Константы обьявляю в "теле" функции, чтоб не светить или по всему коду. Вроде как для отимизации памяти.

 

int WHELL_MIN = 63;  // Минимум джойстика
int WHEEL_MID = 406;  // нейтраль джойстика
int WHEEL_MAX = 672;  // максимум джойстика
int ANGLE_MIN = 75;  // крайнее положение поворота
int ANGLE_MID = 90;  // колеса прямо
int ANGLE_MAX = 105;  // крайнее положение поворота
int GAPE = 2;         // люфт руля


 if(steering <= WHEEL_MID - GAPE)
     {frontWheel.write(map(WHELL_MIN, WHEEL_MID , ANGLE_MIN<ANGLE_MID));
     Serial.println("   Right");}

  if(steering < WHEEL_MID - GAPE && steering > WHEEL_MID + GAPE)
      {frontWheel.write(ANGLE_MID);
      Serial.println("   Middle");}
      
 if (steering >= WHEEL_MID + GAPE)
    {frontWheel.write(map(WHEEL_MID, WHEEL_MAX, ANGLE_MID, ANGLE_MAX));
    Serial.println("   Left");
    }

При проверке выстреливает ошибка:
 

exit status 1
too few arguments to function 'long int map(long int, long int, long int, long int, long int)'
 
Отсюда вопрос, как ее победить?
DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

передать ей 5 параметров, как она просит

vdm
vdm аватар
Offline
Зарегистрирован: 29.08.2016

Добавил:
 

 if(steering <= WHEEL_MID - GAPE)
     {frontWheel.write(map(steering, WHELL_MIN, WHEEL_MID - 1, ANGLE_MIN<ANGLE_MID - 1));
     Serial.println("   Right");}

 

Ошибка та-же

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

а тут вапще 3 передаюца

map(WHELL_MIN, WHEEL_MID , ANGLE_MIN<ANGLE_MID)

vdm
vdm аватар
Offline
Зарегистрирован: 29.08.2016

DetSimen пишет:

а тут вапще 3 передаюца

map(WHELL_MIN, WHEEL_MID , ANGLE_MIN<ANGLE_MID)

 

Косяк при копировании.

Читать:
 

     {frontWheel.write(map(steering, WHELL_MIN, WHEEL_MID - 1, ANGLE_MIN, ANGLE_MID - 1));

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

ну и дак чо?

vdm
vdm аватар
Offline
Зарегистрирован: 29.08.2016

а ни чо.. не робит.

-- update --

а ты злой. Теперь робит!

 

Спасибо за помошь!