джойстик на датчиках холла

alhimik40
Offline
Зарегистрирован: 08.03.2021

Здравствуйте. собираю кастомный геймпад на основе леонардо и с самодельными стиками. 

скетч и библиотеку взял с https://www.partsnotincluded.com/how-to-emulate-an-xbox-controller-with-arduino-xinput/
прошил по инструкции  и взял за основу пример  https://github.com/dmadison/ArduinoXInput/blob/master/examples/GamepadPins/GamepadPins.ino
проблема возникла со стиками на датчиках холла. 
во первых сигнал регистрируется только на 2\3 несмотря на то что до центра магнитов есть еще место. 
во вторых отклонение стика запланированно на 25 градусов но уже при отклонении стика на 10 град все эти 2\3 сигнала оказываются пройдеными. 
подскажите как совместить стики?

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

А где схема и программа? Хрустальные шары нам СТРОГО запрещены гуру этого форума.

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Согласен на все 100% про код и схему, но еще я не понимаю что означает это высказывание:

alhimik40 пишет:

сигнал регистрируется только на 2\3 несмотря на то что до центра магнитов есть еще место. 

во вторых отклонение стика запланированно на 25 градусов но уже при отклонении стика на 10 град все эти 2\3 сигнала оказываются пройдеными.

Я конечно  же заграничных институтов не кончал, да и в принципе с датчиками холла только на автомобилях и велосипедах сталкивался, поэтому отношу данные датчики к "регистраторам метки". О каких 2/3 идет речь и каких 10 градусах - понятия не имею. Поясните.

 

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

BOOM пишет:

Я конечно  же заграничных институтов не кончал, да и в принципе с датчиками холла только на автомобилях и велосипедах сталкивался, поэтому отношу данные датчики к "регистраторам метки". О каких 2/3 идет речь и каких 10 градусах - понятия не имею. Поясните.

 

Датчики Холла они разные бывают. Бинарные (превысило магнитное поле порог или нет) и линейные (аналоговые) - выдающие напряжение в зависимости от величины магнитного поля.

alhimik40
Offline
Зарегистрирован: 08.03.2021

датчики аналоговые ss49e
при максимальном приближении полюса магнита стик отклоняется на 2\3 см фото. 

/*
 *  Project     Arduino XInput Library
 *  @author     David Madison
 *  @link       github.com/dmadison/ArduinoXInput
 *  @license    MIT - Copyright (c) 2019 David Madison
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 *  Example:      GamepadPins
 *  Description:  Uses all of the available pin inputs to build a 'complete'
 *                Xbox gamepad, with both analog joysticks, both triggers,
 *                and all of the main buttons.
 *
 *                * Joysticks should be your typical 10k dual potentiometers.
 *                  To prevent random values caused by floating inputs,
                    joysticks are disabled by default.
 *                * Triggers can be either analog (pots) or digital (buttons).
 *                  Set the 'TriggerButtons' variable to change between the two.
 *                * Buttons use the internal pull-ups and should be connected
 *                  directly to ground.
 *
 *                These pins are designed around the Leonardo's layout. You
 *                may need to change the pin numbers if you're using a
 *                different board type
 *
 */

#include <XInput.h>

// Setup
const boolean UseLeftJoystick   = true;  // set to true to enable left joystick
const boolean InvertLeftYAxis   = false;  // set to true to use inverted left joy Y

const boolean UseRightJoystick  = true;  // set to true to enable right joystick
const boolean InvertRightYAxis  = false;  // set to true to use inverted right joy Y

const boolean UseTriggerButtons = false;   // set to false if using analog triggers

const int ADC_Max = 1023;  // 10 bit

// Joystick Pins
const int Pin_LeftJoyX  = A0;
const int Pin_LeftJoyY  = A1;
const int Pin_RightJoyX = A2;
const int Pin_RightJoyY = A3;

// Trigger Pins
const int Pin_TriggerL = A4;
const int Pin_TriggerR = A5;

// Button Pins
const int Pin_ButtonA = 0;
const int Pin_ButtonB = 1;
const int Pin_ButtonX = 2;
const int Pin_ButtonY = 3;

const int Pin_ButtonLB = 4;
const int Pin_ButtonRB = 5;

const int Pin_ButtonBack  = 6;
const int Pin_ButtonStart = 7;

const int Pin_ButtonL3 = 8;
const int Pin_ButtonR3 = 9;

// Directional Pad Pins
const int Pin_DpadUp    = 10;
const int Pin_DpadDown  = 11;
const int Pin_DpadLeft  = 12;
const int Pin_DpadRight = 13;

void setup() {
	// If using buttons for the triggers, use internal pull-up resistors
	if (UseTriggerButtons == false) {
		pinMode(Pin_TriggerL, INPUT_PULLUP);
		pinMode(Pin_TriggerR, INPUT_PULLUP);
	}
	// If using potentiometers for the triggers, set range
	else {
		XInput.setTriggerRange(0, ADC_Max);
	}

	// Set buttons as inputs, using internal pull-up resistors
	pinMode(Pin_ButtonA, INPUT_PULLUP);
	pinMode(Pin_ButtonB, INPUT_PULLUP);
	pinMode(Pin_ButtonX, INPUT_PULLUP);
	pinMode(Pin_ButtonY, INPUT_PULLUP);

	pinMode(Pin_ButtonLB, INPUT_PULLUP);
	pinMode(Pin_ButtonRB, INPUT_PULLUP);

	pinMode(Pin_ButtonBack, INPUT_PULLUP);
	pinMode(Pin_ButtonStart, INPUT_PULLUP);

	pinMode(Pin_ButtonL3, INPUT_PULLUP);
	pinMode(Pin_ButtonR3, INPUT_PULLUP);

	pinMode(Pin_DpadUp, INPUT_PULLUP);
	pinMode(Pin_DpadDown, INPUT_PULLUP);
	pinMode(Pin_DpadLeft, INPUT_PULLUP);
	pinMode(Pin_DpadRight, INPUT_PULLUP);

	XInput.setJoystickRange(0, ADC_Max);  // Set joystick range to the ADC
	XInput.setAutoSend(false);  // Wait for all controls before sending

	XInput.begin();
}

void loop() {
	// Read pin values and store in variables
	// (Note the "!" to invert the state, because LOW = pressed)
	boolean buttonA = !digitalRead(Pin_ButtonA);
	boolean buttonB = !digitalRead(Pin_ButtonB);
	boolean buttonX = !digitalRead(Pin_ButtonX);
	boolean buttonY = !digitalRead(Pin_ButtonY);

	boolean buttonLB = !digitalRead(Pin_ButtonLB);
	boolean buttonRB = !digitalRead(Pin_ButtonRB);

	boolean buttonBack  = !digitalRead(Pin_ButtonBack);
	boolean buttonStart = !digitalRead(Pin_ButtonStart);

	boolean buttonL3 = !digitalRead(Pin_ButtonL3);
	boolean buttonR3 = !digitalRead(Pin_ButtonR3);

	boolean dpadUp    = !digitalRead(Pin_DpadUp);
	boolean dpadDown  = !digitalRead(Pin_DpadDown);
	boolean dpadLeft  = !digitalRead(Pin_DpadLeft);
	boolean dpadRight = !digitalRead(Pin_DpadRight);

	// Set XInput buttons
	XInput.setButton(BUTTON_A, buttonA);
	XInput.setButton(BUTTON_B, buttonB);
	XInput.setButton(BUTTON_X, buttonX);
	XInput.setButton(BUTTON_Y, buttonY);

	XInput.setButton(BUTTON_LB, buttonLB);
	XInput.setButton(BUTTON_RB, buttonRB);

	XInput.setButton(BUTTON_BACK, buttonBack);
	XInput.setButton(BUTTON_START, buttonStart);

	XInput.setButton(BUTTON_L3, buttonL3);
	XInput.setButton(BUTTON_R3, buttonR3);

	// Set XInput DPAD values
	XInput.setDpad(dpadUp, dpadDown, dpadLeft, dpadRight);

	// Set XInput trigger values
	if (UseTriggerButtons == false) {
		// Read trigger buttons
		boolean triggerLeft  = !digitalRead(Pin_TriggerL);
		boolean triggerRight = !digitalRead(Pin_TriggerR);

		// Set the triggers as if they were buttons
		XInput.setButton(TRIGGER_LEFT, triggerLeft);
		XInput.setButton(TRIGGER_RIGHT, triggerRight);
	}
	else {
		// Read trigger potentiometer values
		int triggerLeft  = analogRead(Pin_TriggerL);
		int triggerRight = analogRead(Pin_TriggerR);

		// Set the trigger values as analog
		XInput.setTrigger(TRIGGER_LEFT, triggerLeft);
		XInput.setTrigger(TRIGGER_RIGHT, triggerRight);
	}

	// Set left joystick
	if (UseLeftJoystick == false) {
		int leftJoyX = analogRead(Pin_LeftJoyX);
		int leftJoyY = analogRead(Pin_LeftJoyY);

		// White lie here... most generic joysticks are typically
		// inverted by default. If the "Invert" variable is false
		// then we'll take the opposite value with 'not' (!).
		boolean invert = !InvertLeftYAxis;

		XInput.setJoystickX(JOY_LEFT, leftJoyX);
		XInput.setJoystickY(JOY_LEFT, leftJoyY, invert);
	}

	// Set right joystick
	if (UseRightJoystick == true) {
		int rightJoyX = analogRead(Pin_RightJoyX);
		int rightJoyY = analogRead(Pin_RightJoyY);

		boolean invert = !InvertRightYAxis;

		XInput.setJoystickX(JOY_RIGHT, rightJoyX, invert);
		XInput.setJoystickY(JOY_RIGHT, rightJoyY, invert);
	}

	// Send control data to the computer
	XInput.send();
}

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Уважаемый, представьте схему. Иначе будут недопонимания и обиды.

Далее - сделайте простую программу опроса портов А0-А3 и выдачи в терминал. Посмотрите чего выдается. Ваша программа непрозрачна, особенно учитывая XInput.

Получите значения - пишите.

svm
Offline
Зарегистрирован: 06.11.2016

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

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

svm пишет:

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

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Значит корень квадратный из измерений. Чего там сложного?

svm
Offline
Зарегистрирован: 06.11.2016

ua6em пишет:

svm пишет:

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

Здесь указана зависимость выходного напряжения от напряженности магнитного поля, а не от расстояния от магнита до датчика. В реальности аналоговый датчик чувствует неодимовый магнит примерно со 150 мм. Как можно на мизерной площади джойстика заставить реагировать датчик на свой магнит не используя какую-то магнитную экранировку? Да и изменения расстояния от магнита до датчика в пределах 1-2 мм будет вызывать дикое изменение выходного сигнала (если напряженность МП находится в рабочем диапазоне датчика). В реальности параметры магнитов очень сильно различаются,  и  для корректной работы нужно очень тщательно выбрать параметры механической части (магнитную систему). Ну и программную часть никто не отменял. Скорее всего в библиотеке она как-то реализована. Но должны быть какие-то ограничения.

rkit
Offline
Зарегистрирован: 23.11.2016

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

svm
Offline
Зарегистрирован: 06.11.2016

rkit пишет:

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

Это немного из другой оперы. В этом случае используют специализированные МС - датчики угла поворота и специальные магниты, а у ТС четыре обычных аналоговых Холла. Хотя идея здравая. Вместо четырех обычных поставить два специальных и проблемы исчезнут.

rkit
Offline
Зарегистрирован: 23.11.2016

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

svm
Offline
Зарегистрирован: 06.11.2016

rkit пишет:
Обычный или двухоснвой датчик холла там используется.

Как пишет ТС "датчики аналоговые ss49e". Странно, у этого датчика, судя по описанию - цифровой выход. Хотя в другом месте, вроде аналоговый как в #7.

-NMi-
Offline
Зарегистрирован: 20.08.2018

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

Кто из мск - могу показать этот самый джойстик (неисправный).

ps: можно срубить баблеца, если вывезем тему! Джойстики 2-х и 3-х координатные, управляют всякими разными грузоподъёмными механизмами.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

-NMi- пишет:

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

Кто из мск - могу показать этот самый джойстик (неисправный).

ps: можно срубить баблеца, если вывезем тему! Джойстики 2-х и 3-х координатные, управляют всякими разными грузоподъёмными механизмами.

всё давно придумано до нас

alhimik40
Offline
Зарегистрирован: 08.03.2021

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

как вариант попробую поставить 10ком резистор может поможет 

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

alhimik40 пишет:

как вариант попробую поставить 10ком резистор может поможет 

А смысл? Пользуйтесь диапазоном min-max. Все равно большего разрешения Вы не получите.

Если оч надо такой диапазон - используйте map()