Управление трактором с помощью джойстика

Всем доброго времени суток.
Я создаю трактор. Не большой но очень комфортный. Кратко о конструкции. Бензиновый двигатель создаёт давлени в гидросистеме и с помощью давления гидравлики управляются почти все процессы.
Сейчас я столкнулся с очередным вопросом. В движение трактор приводится четырьмя гидродвигателями расположенными на каждом колесе. Схема распространенная, но есть одно но. Гидро давлени подаётся на гидромоторы специальным гидрораспределителем который управляется электромагнитными соленоидами. В свою очередь в кабине стоит джойстик от компьютера. Получается при отклонении джойстика вперёд трактор начинает движение вперёд. Чем сильнее отклонил джойстик тем быстрее поехал трактор. При отклонении джойстика строго в сторону трактор начинает кружится на месте чем сильнее отклоняешь тем быстрее вращается трактор. Ну и соответственно при отклонении назад он двигается назад . Если же при максимальном отклонении вперёд начинаешь отклонять джойстик в сторону одна из сторон движения замедляется и при полном отклонении вперёд и в сторону одна из сторон полность останавливается. Вторая продолжает движение на полной скорости. В общем как на танке только управление с помощью джойстика.
Задача:
Есть джойстик Ардуино Уно. И соленоиды 4 шт
В джойстике установлены два датчика холла.
Я подключил их к ардуино через аналоговый вход А0 и измерил показания одного из датчиков холла. Показания нейтральное положение 510, отклонение вперёд полностью 390, полностью назад 630. В чем это я не знаю это в программе на странице мониторинга на компе. Соленоиды работают так:
При подаче напряжения от 0 до 5 вольт. Получается от минимального значения 0. До максимального значения 5 вольт. Имеется два канала управления левой стороной и правой стороной. На каждом канале два соленоида. Один соленоид управляет движением вперёд другой соленоид управляет движением назад. От 0 до 5 вольт имеется ввиду ШИМ сигнал с ардуино. Т к. Мои знания программирования ограничиваются прочтением книжки которую посоветовали на этом сайте. Трудно со всем разобраться самому. Помогите кто может.
Примеры из книжки не работали. А вот программа из видео подключения датчика холла заработала. Что позволило получить измерения. Скрин программы прикреплю. Всем заранее спасибо.

А соленоидами в гидравлической системе вы ШИМом управлять собираетесь? Они работают в режиме “вкл/выкл” или “аналоговые”?

Они работают от 5 до 24 вольт. Я собрал 4 канальную электрическую схему. Которая преобразует ШИМ сигнал от 0 до 5 вольт в выходное напряжение от 5 до 24 вольт соответственно. Я не стал этот момент прописывать. Чтобы не загружать данный вопрос.

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

А можно точную маркировку блока соленоидов?
А код вставьте как положено- скрин нечетабельный.
Я делал машинку (практиковался ) с управлением джойстиком. Было реализовано управление похожее на то , что нужно вам. Движение вперед назад, развороты,изменение скорости в зависимости от отклонения джойстика от центра и т. д.
ШИМил четыре мотора.

Есть фото соленоидов. И их сопротивление 20 Ом каждого

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

Полностью с Вами согласен. Я из Китая заказал именно пропорциональный гидрораспределитель с механическим управлением и электрическим. Сначала хотел сделать механическое управление, но потом решил заморочится на электрических сигналах. Просто у меня плавающая как на фуре кабина и откидывается тоже как на фуре. И тянуть гидропроводку из кабины сложно и не нужно. Кому интересно двухканальный такой гидрораспределитель из Китая примерно 50 тр. Курс все время меняется. Сейчас веду переговоры сразу на все поставить пропорциональные гидрораспределитель. В общем 8 каналов стоит примерно 150 тр. И это гораздо дешевле потому что ваши примеры с ценами это правда.

int Led = 13 ;
int SENSOR = 10 ;
int ANALOGSENSOR = A0 ;
int val ;
void setap ()
{
pinMode ( Led, OUTPUT) ;
pinMode ( SENSOR, INPUT) ;
Serial.begin ( 9600 ) ;
}
void loop ()
{
val = digitalRead ( SENSOR ) ;
if ( val == LOW )
{
digitalWrite ( Led, HIGH ) ;
}
else
{
digitalWrite ( Led, LOW ) ;
}
Serial.print ( "Sensor: ") ;
Serial.println (analogRead (ANALOGSENSOR)) ;
}

Все четыре мотора управлялись отдельно. Были установлены

такие колеса. Плавно изменялась скорость вращения колес в зависимости от положения джойстика. Я отрабатывал на машинке управление через ДУ на основе LoRa модуля.И за одно неплохая игрушка для деток.

Ещё я подумал про логику движения. И пришел к мысли что придется использовать третий датчик холла который расположен в ручке джойстика на ее вращение в лево и вправо. Наверное так будет удобней.
Получается начинаешь перемещать джойстик вперёд, получаем движение вперёд. При отклонение в этот момент в сторону начинается ограничение скорости движения той стороны в которую отклонил джойстик. При полном отклонении в сторону имеем полную остановку одной из сторон. Другая работает с той скоростью на которую отклонен джойстик вперёд. А чтобы получить вращение на месте нужно повернуть рукоядку влево или вправо. А как этот момент был реализован в Вашей машинке?

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

Две оси джойстика вполне достаточно.Я использовал джойстик с двумя переменными резисторами и кнопкой- на вид как в джойстике от PS.
Использовал функцию map -много. Для плавного поворота влево-вправо использовал cos от угла поворота , который функцией map получал от среднего положения джойстика до крайнего левого(правого) считая равным его в среднем положении равным 0, а в крайних положениях -90гр . .Это вкратце .

Скетч найти попробую-делал около пяти -шести лет назад.

Ещё хотел узнать можно написать зависимость изменяем джойстик от 510 до 390 у нас пропорционально меняется напряжение (ШИМ от0 до 255) или нужно прописывать каждое изменение джойстика?
Например 450. ШИМ 150.

Нет, не надо.

Но потом, на реальном тракторе, может и понадобится.

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

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

" … КВС несколько раз отклонил ручку управления вперёд и назад с большой амплитудой (вплоть до максимальных значений), что привело к изменению [угла тангажа] в диапазоне от +6 до −2°"
По мнению ВКС - " … к катастрофе привела «некорректная» реакция самолёта на действия ручкой управления во время посадки."
из - Катастрофа SSJ 100 в аэропорту Шереметьево 2019 г.

это в 10-битных целых числах Функция analogRead() | Аппаратная платформа Arduino ближайший подходящий тип данных uint16_t

Вот эту часть могу подсказать. У вас орган управления имеет для каждой оси, грубо говоря, три ключевые точки: min, mid, max (минимум, среднее, максимум). Надо для начала сделать алгоритм калибровки, например по нажатию кнопки, который позволит откалибровать, то есть определить эти min, mid, max. Например, нажали кнопку, заморгал светодиод (или другая индикация) - пользователь должен ручку подергать во все крайние положения (алгоритм при этом min и max обновляет). Еще раз кнопку нажали - другая индикация, пользователь не должен трогать ручку, калибруется mid (центр) например среднее арифметическое от 50 замеров подряд. Потом индикация гаснет, калибровка завершена, значения пишутся в EEPROM.

Итак у вас для каждой оси свои min, mid, max

Теперь желательно эти значения привести к фиксированному диапазону, подойдет линейное масштабирование, с этим справляется функция map(). Определяете свои MIN, MID и MAX, ну например -500, 0, 500, и если текущее показание с оси джойстика у вас x, то:

X = x < mid ? map(x, min, mid, MIN, MID) : map(x, mid, max, MID, MAX);

такой же принцип по Y (внимательно! min, mid, max для этой оси у вас будут другие)
Еще желательно добавить небольшую мертвую зону в центральном положении ручки:

dz = 10;
if (abs(x - mid) < dz) X = MID;
else X = x < mid ? map(x, min, mid - dz, MIN, MID) : map(x, mid + dz, max, MID, MAX);

типы данных подберете сами, будут вопросы - спрашивайте

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

Всем доброго времени суток!
Здорово!
Тогда просто помогите сначала с простым.
Вот эту простую программу для замера значений преобразовать на три датчика холла.
Чтобы их измерить. Или придется каждый отдельно подключать и смотреть?
А ещё лучше сразу можно что нибудь накинуть. Я задавал этот вопрос искусственному интеллекту. Он конечно выдал программу но мне самому понять как правильно обозначать три разных датчика?

const int hall_1Pin_analog = A0; // Пин датчика Холла 1 (вперед/назад)
const int hall_2Pin_analog = A1; // Пин датчика Холла 2 (поворот)
const int hall_3Pin_analog = A2; // Пин датчика Холла 3 (вращение)

const int valve_APin = 9; // Пин для управления электромагнитом A (вперед левая)
const int valve_BPin = 10; // Пин для управления электромагнитом B (вперед правая)
const int valve_CPin = 11; // Пин для управления электромагнитом C (назад левая)
const int valve_DPin = 12; // Пин для управления электромагнитом D (назад правая)

const int neutralPosition = 510; // Нейтральное положение датчиков Холла
const int forwardPosition = 390; // Крайнее положение вперед
const int backwardPosition = 630; // Крайнее положение назад

void setup() {

Так первая часть правильно?
Или ещё что-то нужно прописать
Я сейчас в командировке ещё 3 дня поэтому не могу сразу проверить. Это предложил искусственный интеллект он подчеркивания не ставит между словами. Я кое где сам подставил.

const int hall_1Pin_analog = A0; // Пин датчика Холла 1 (вперед/назад)
const int hall_2Pin_analog = A1; // Пин датчика Холла 2 (поворот)
const int hall_3Pin_analog = A2; // Пин датчика Холла 3 (вращение)

const int valve_APin = 9; // Пин для управления электромагнитом A (вперед левая)
const int valve_BPin = 10; // Пин для управления электромагнитом B (вперед правая)
const int valve_CPin = 11; // Пин для управления электромагнитом C (назад левая)
const int valve_DPin = 12; // Пин для управления электромагнитом D (назад правая)

const int neutralPosition = 510; // Нейтральное положение датчиков Холла
const int forwardPosition = 390; // Крайнее положение вперед
const int backwardPosition = 630; // Крайнее положение назад

void setup()
{
pinMode(valveAPin, OUTPUT);
pinMode(valveBPin, OUTPUT);
pinMode(valveCPin, OUTPUT);
pinMode(valveDPin, OUTPUT);
Serial.begin(9600);
}

void loop() {

Помогите вставить. Как это привязать к моим обозначениям. Может переименовать в начале условия. В общем как связать одно с другим?

X = x < mid ? map(x, min, mid, MIN, MID) : map(x, mid, max, MID, MAX);

dz = 10;
if (abs(x - mid) < dz) X = MID;
else X = x < mid ? map(x, min, mid - dz, MIN, MID) : map(x, mid + dz, max, MID, MAX);