Джойстик для arduino (Itead JoyStick)


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

Ссылка на BTboard

Однако другие модели модулей джойстиков имеют существенный недостаток — они по габаритам больше платы ардуино.

Но вернемся к ардуино, есть варианты, в которых предусмотрены места для пайки

Поскольку и плата и джойстик у меня давно, то в ардуино уже впаян UART разъем и отсутствует кварц (брак).Следует отметить, что отсутствие кварца подразумевает наличие у вас ISP программатора, не важно какого, хоть целая и здоровая ардуина с соответствующей прошивкой.
Дальше я взял пару аккумуляторов на 240 mah и соеддинил последовательно, получив 8.4В на выходе.

По форме и объему они очень органично вписались в свободное место на плате, где все прекрасно соединяется поставленными разъемами, и вывел балансировочный разъем на 3P для зарядки аккумулятора

Рядышком примастился блютус модуль HC-05

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

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

Который легко и непринужденно заряжается вот такой USB зарядкой

Теперь немного конкретики, на этот джойстик на просторах интернета есть даташит, приведу из него основную информацию, больше там смотреть особо не на что
PCB size 53.3mm X 68.6mm X 1.6mm
Power supply 5V/3.3V DC


В работе пульт показал себя отлично, тем кому интересно выкладываю код на С++, т.к. программист из меня не очень, комментарии подробнейшие, иначе я через неделю запутаюсь в собственной писанине и не смогу адекватно поправить программу. Тест проводил в программе terminal-1.9b, используя два связанных в пару блютус модуля и USB-UART конвертер. Косяков нет, все рабочее.
Немного кода, писал в Atmel Studio

/********************************************************
В результате на выходе UART получим значения от 1 до 7
соответствующие кнопкам от А до G, при этом пятый бит
должен быль =1 (признак кнопок). И 8 бит от джостика
где старшие 2 бита ось и направление по ней, 5 бит =0,
биты 0-4 величина отклонения от нуля.
********************************************************/
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#define FOSC 16000000UL // Clock Speed
#define BAUD 9600
#define MYUBRR FOSC/16/BAUD-1
bool ADC_chanel=0;
char data;
const int zz=1, z=250;//zz - как часто отправляем данные
//Инициализация UART 8 бит данных, 2 стоп бит, бит четности - передатчик
void USART_Init( unsigned int ubrr)
{
	//Set baud rate
	UBRR0H= (unsigned char)(ubrr>>8);
	UBRR0L= (unsigned char)ubrr;
	//Enable transmitter
	UCSR0B|= (1<<TXEN0);
	// Set frame format: 8data, Odd Parity, 2stop bit
	UCSR0C|= (1<<UCSZ00)|(1<<UCSZ01)|(1<<UPM00)|(1<<UPM01)|(1<<USBS0);
	}
//Инициализация АЦП
void ADC_init (void)
	{
		//вкл. АЦП(ADEN), разрешение прерывания(ADIE), пределитель 128(ADPS2..ADPS0)
		ADCSRA|=(1<<ADEN)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
		// источник напряжения AVcc(REFS1..REFS0), в данном случае напряжение питания микросхемы
		ADMUX|=(1<<ADLAR)|(0<<REFS1)|(1<<REFS0);
		//выбор входного канала PORTC.0 (MUX4..MUX0)
		ADMUX|=(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(0<<MUX0);
		//Запуск преобразования АЦП (одиночное преобразование), для нового измерения повторяем эту строку
		ADCSRA|= (1 << ADSC);
	}
//вектор прерывания от АЦП	
ISR  (ADC_vect)
{
	//меняем входной канал, инвертируя бит MUX0, переходим с ноги PC0 на PC1 и обратно		
	ADMUX ^=(1<<MUX0);		
	//запоминаем в переменную, теперь есть чем выбрать оси Х и У
	ADC_chanel=!ADC_chanel;	
}
//обработка данных с АЦП
void xy_data(void)
{
//джостик четко стоит на 127 (от 0 до 255) по обоим осям
//чтобы постоянно не отправлять нули и экономить батарейку
//исключаем нулевые значения
if (ADCH!=127)	
	{
	//если ADC_chanel=1 мы измеряем значение по оси х, чтобы это зафиксировать
	//будет использоваться 7 (последний) бит посылки =1
		if (ADC_chanel==0)  
		{
	//ось х, при движении направо для фиксации события используем 6 бит =1	
			if (ADCH>130)	
			{
	/*Чтобы освободить те самые 3 старших бита посылки (6 и 7 бит признак оси, 5=0 бит
	признак кнопки, 0-4 биты величина отклонения пооси или номер кнопки), пришлось уменьшить
	количество значений до 32 (5 бит данных)*/	
				data = (ADCH-127)/4-1;//максимальное значение 31
	//отмечаем в каком направлении происходит движение джостика, в данном случае направо по оси х		
				data|= (1<<7)|(1<<6);
	//отсылаем пакет по UART
				UDR0 = data;
			}
	//ось х, движение налево, 6 бит остается =0		
			if(ADCH<124)	
			{
				data=(-(ADCH-128))/4-1;
				data|= (1<<7);
				UDR0 = data;
			}
		}
		else				//ось у, 7 бит =0
		{
			if (ADCH>130)	//ось у, движение вперед, 6 бит =1
			{
				data = (ADCH-127)/4-1;
				data|= (1<<6);
				UDR0 = data;
			}
			if(ADCH<124)	//ось у, движение назад,  6 бит =0
			{
				data=(-(ADCH-128))/4-1;
				UDR0 = data;
			}
		}
	}
}
//работа с кнопками
void button (void)
{
	//на первых битах находится порт UART, а именно ноги TX RX, чтобы не иметь проблем
	//сдвинул значение на 2 бита. Все пины порта D за исключением этих двух подтянуты к 1
	//и появление на них 0 - признак нажатой кнопки. Ждем нажатия.
	switch ( (PIND>>=2) )
	{
		case 0b00011111://кнопка А и так далее, F, G висят на PB0, PB1
		//формат посылки 5 бит=1 признак нажатой кнопки 0-2 бит номер кнопки
		UDR0=0b00100001;
		_delay_ms(z);	//избавляемся от дребезга
		break;
		case 0b00101111://B
		UDR0=0b00100010;
		_delay_ms(z);
		break;
		case 0b00110111://C
		UDR0=0b00100011;
		_delay_ms(z);
		break;
		case 0b00111011://D
		UDR0=0b00100100;
		_delay_ms(z);
		break;
		case 0b00111101://Е
		UDR0=0b00100101;
		_delay_ms(z);
		break;
	}
	if ((PINB & (1<<0)) == 0)
	{
		UDR0=0b00100110;//F
		_delay_ms(z);
	}
	if ((PINB & (1<<1)) == 0)
	{
		UDR0=0b00100111;//G
		_delay_ms(z);
	}
}
int main(void)
{
	DDRB=0x00;
	PORTB=0x00;
	DDRD=0x00;
	PORTD=0x00;
	USART_Init(MYUBRR);
	ADC_init();
	sei(); //разрешаем прерывания
	while (1)
	{
	//ждем нажатия кнопки
	button();		
	//обрабатываем данные с АЦП, получая направление и величину отклонения по осям
	//иначе говоря положение джостика
	xy_data();
	// повторно запуск преобразования АЦП
	ADCSRA |= (1 << ADSC);
	//как часто реагируем на работу с джойстиком
	_delay_ms(zz);
	}
}

Результат нажатия кнопок. Пятый бит всегда =1, это означает, что кнопка нажата, биты с 0 по 2 — номер кнопки.


Движение джойстика вверх. 6-7 бит направление по оси, 5 бит =0 (ни одна кнопка не нажата), 0-4 биты отклонение джойстика от центра. В данном случае движение по оси У вверх, 6-7 биты =01, максимальное значение получается процентов за 5-7 до упора джойстика


Кошка

Распаковки нет, т.к. посылка пришла достаточно давно.
Планирую купить +14 Добавить в избранное +20 +39
+
avatar
  • maxi911
  • 23 декабря 2015, 15:43
0
Зарядка с балансировкой? Можно ссылочку на нее?
+
avatar
+2
Внутрь не смотрел, но напряжение на аккумуляторах одинаковое, значит балансир таки есть, перезаряда нет, 8.35В в сумме. Зарядку брал уже в Москве на авито, вот ссылка на али.
aliexpress.com/item/7-4V-Lipo-Battery-USB-Charger-Cable-For-WLtoys-V912-V913-V915-V262-V323-V333-V666/32513826142.html,searchweb201644_4_79_78_77_82_80_62,searchweb201560_3
+
avatar
  • fundorin
  • 23 декабря 2015, 16:23
0
Для чего пульт? И чем не устроил готовый вариант?
+
avatar
+1
Дух охоты! Желание творить, и прочее и прочее.
+
avatar
0
А можно узреть применение?
+
avatar
+2
ДУ управление. Ответная часть для пульта в пути.
aliexpress.com/item/T500-Smart-Tank-Car-with-Shock-Absorber-Silver-Version-Aluminum-Alloy-Chassis-experiment-platform-servos-controller/32479892107.html
Иными словами будет обзор на шасси, аккумуляторы 18650 — 6 шт, контроллер заряда, блок питания, драйвера двигателя. В идеале все будет ездить :)
Вполне возможно сделаю плату сам, тут уж как получится. Будет это, скорее всего, в феврале месяце.
+
avatar
  • e777kx11
  • 24 декабря 2015, 00:45
0
Как стик работает? От начало до конца, до упора работает? Или рабочий ход маленький, а остальной в холостую? Имею ввиду изменение сигнала при использование его.
+
avatar
+1
Процентов 5-7 сверху и столько же снизу холостой ход, Т.е., 15% хода стабильные крайние значения, весьма неплохой результат, на мой взгляд. Добавил пару скринов работы проги.
+
avatar
  • maxi911
  • 23 декабря 2015, 16:36
0
Кстати, советую все таки впаять кварц на 12мгц. Зачем отказываться от USB-UART переходника на борту ардуинки?
+
avatar
0
У меня есть ISP программатор mkII, который работает с Atmel Studio 6.2. Больше программировать эту ардуинку я не буду, так что и не зачем покупать лишние детали. Конечно жаль, что купил бракованную плату, но я не особо расстроился и извлек из этого нечто полезное.
+
avatar
  • NAgain
  • 23 декабря 2015, 17:03
+2
За православный СИ-шный код — дай я тебя обниму!
+
avatar
  • wright
  • 23 декабря 2015, 18:38
+1
+1
я тоже немного удивился что с++, раскрыл код, а там честный си )))))