Joystik для ПК на базе Arduino
Перво-наперво необходимо было научиться считывать и обрабатывать сигналы со стиков и управлять курсором напрямую с Arduino Pro Micro.
#include
const int X1_Pin = A0;
const int Y1_Pin = A1;
const int X2_Pin = A2;
const int Y2_Pin = A3;
const int SW1_Pin = 3;
const int SW2_Pin = 2;
int SW1_Stage;
int SW2_Stage;
int SW1;
int SW2;
const int Sp = 5;
void setup() {
Serial.begin(9600);
Mouse.begin();
pinMode(SW1_Pin, INPUT_PULLUP);
pinMode(SW2_Pin, INPUT_PULLUP);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
}
void loop() {
//Доп пины питания
digitalWrite(8, HIGH);
digitalWrite(9, HIGH);
//Чтение портов
int x1 = analogRead(X1_Pin);
int y1 = analogRead(Y1_Pin);
int x2 = analogRead(X2_Pin);
int y2 = analogRead(Y2_Pin);
SW1_Stage = digitalRead(SW1_Pin);
SW2_Stage = digitalRead(SW2_Pin);
int x1pos, y1pos;
int x2pos, y2pos;
//Фильтр XY1
if (x1 > 450 and x1 < 550)
x1pos = 0;
if (x1 >= 550)
x1pos = map(x1, 550, 1023, 0, Sp);
if (x1 <= 450)
x1pos = map(x1, 450, 0, 0, -Sp);
if (y1 > 450 and y1 < 550)
y1pos = 0;
if (y1 >= 550)
y1pos = map(y1, 550, 1023, 0, Sp);
if (y1 <= 450)
y1pos = map(y1, 450, 0, 0, -Sp);
//Обработка кнопки ЛКМ
if (SW1_Stage == LOW)
SW1 = 1;
else
SW1 = 0;
//Фильтр XY2
if (x2 > 450 and x2 < 550)
x2pos = 0;
if (x2 >= 550)
x2pos = map(x2, 550, 1023, 0, Sp);
if (x2 <= 450)
x2pos = map(x2, 450, 0, 0, -Sp);
if (y2 > 450 and y2 < 550)
y2pos = 0;
if (y2 >= 550)
y2pos = map(y2, 550, 1023, 0, Sp);
if (y2 <= 450)
y2pos = map(y2, 450, 0, 0, -Sp);
//Обработка кнопки ПКМ
if (SW2_Stage == LOW)
SW2 = 1;
else
SW2 = 0;
//Управление курсором
Mouse.move(x1pos, y1pos);
if (SW1) {
Mouse.press(MOUSE_LEFT);
} else {
Mouse.release(MOUSE_LEFT);
}
if (SW2) {
Mouse.press(MOUSE_RIGHT);
} else {
Mouse.release(MOUSE_RIGHT);
}
/*/Отладка
Serial.print(x1pos);
Serial.print(":");
Serial.print(y1pos);
Serial.print(":");
Serial.println(SW1_Stage);
Serial.print(":");
Serial.print(x2pos);
Serial.print(":");
Serial.print(y2pos);
Serial.print(":");
Serial.println(SW2_Stage);
/*/
delay(10);
}
А теперь самое интересное! Объединить эти два кода. Не обошлось и без плясок с бубном, и убегающим в «самоволку» курсором.
TX:
#include
#include "nRF24L01.h"
#include "RF24.h"
RF24 radio(9, 10); //Создать модуль на пинах 9 и 10
byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"}; //возможные номера труб
const int XL_Pin = A0; //Аналоговый вход левого стика ось X
const int YL_Pin = A1; //Аналоговый вход левого стика ось Y
const int XR_Pin = A2; //Аналоговый вход правого стика ось X
const int YR_Pin = A3; //Аналоговый вход правогоо стика ось Y
byte LBM_Pin = 2; //Цифровой вход ЛКМ
byte RBM_Pin = 3; //Цифровой вход ПКМ
byte transmit_data[6]; //Массив, хранящий передаваемые данные
byte latest_data[6]; //Массив, хранящий последние переданные данные
boolean flag; //Флаг отправки данных
void setup() {
Serial.begin(9600); //Открываем порт для связи с ПК
pinMode(XL_Pin, INPUT); //Настройка порта левого стика ось X
pinMode(YL_Pin, INPUT); //Настройка порта левого стика ось Y
pinMode(XR_Pin, INPUT); //Настройка порта правого стика ось X
pinMode(YR_Pin, INPUT); //Настройка порта правого стика ось Y
pinMode(LBM_Pin, INPUT_PULLUP); //Настройка порта ЛКМ
pinMode(RBM_Pin, INPUT_PULLUP); //Настройка порта ЛКМ
pinMode(7, OUTPUT); //Доп питание
pinMode(8, OUTPUT); //Доп питание
digitalWrite(7, HIGH); //Доп пин питания левого стика
digitalWrite(8, HIGH); //Доп пин питания правого стика
radio.begin(); //Активировать модуль
radio.setAutoAck(1); //Режим подтверждения приёма, 1 вкл 0 выкл
radio.setRetries(0, 15); //Время между попыткой достучаться, число попыток
radio.enableAckPayload(); //Разрешить отсылку данных в ответ на входящий сигнал
radio.setPayloadSize(32); //Размер пакета, в байтах
radio.openWritingPipe(address[0]); //Труба 0, открыть канал для передачи данных
radio.setChannel(0x70); //Выбираем канал (в котором нет шумов!)
radio.setPALevel (RF24_PA_MAX); //Уровень мощности передатчика. На выбор RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX
radio.setDataRate (RF24_250KBPS); //Скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS должна быть одинакова на приёмнике и передатчике!при самой низкой скорости имеем самую высокую чувствительность и дальность!!
radio.powerUp(); //Начать работу
radio.stopListening(); //Не слушаем радиоэфир, мы передатчик
}
void loop() {
//Чтение портов
transmit_data[0] = map(analogRead(XL_Pin), 0, 1023, 0, 255); //Записать значение XL на 1 место в массиве
transmit_data[1] = map(analogRead(YL_Pin), 0, 1023, 0, 255); //Записать значение YL на 2 место в массиве
transmit_data[2] = map(analogRead(XR_Pin), 0, 1023, 0, 255); //Записать значение XR на 3 место в массиве
transmit_data[3] = map(analogRead(YR_Pin), 0, 1023, 0, 255); //Записать значение YR на 4 место в массиве
transmit_data[4] = !digitalRead(LBM_Pin); //Записать сигнал ЛКМ на 5 место в массиве
transmit_data[5] = !digitalRead(RBM_Pin); //Записать сигнал ПКМ на 5 место в массиве
radio.powerUp(); // включить передатчик
radio.write(&transmit_data, sizeof(transmit_data)); // Отправить по радио
for (int i = 0; i < 6; i++) { // В цикле от 0 до числа каналов
if (transmit_data[i] != latest_data[i]) { // Если есть изменения в transmit_data
flag = 1; // Поднять флаг отправки по радио
latest_data[i] = transmit_data[i]; // Запомнить последнее изменение
}
}
if (flag == 1) {
radio.powerUp(); // Включить передатчик
radio.write(&transmit_data, sizeof(transmit_data)); // Отправить по радио
flag = 0; // Опустить флаг
radio.powerDown(); // Выключить передатчик
}
/*/Отладка, проверка сигнала на A0,A1,A2,A3
Serial.print(analogRead(XL_Pin));
Serial.print(":");
Serial.print(analogRead(YL_Pin));
Serial.print(":");
Serial.println(!digitalRead(2));
Serial.print("\n");
Serial.print(analogRead(XR_Pin));
Serial.print(":");
Serial.print(analogRead(YR_Pin));
Serial.print(":");
Serial.println(!digitalRead(3));
delay(10);
*/
}
//Список занятых пинов: A0,A1,A2,A3,1,2,3,4,7,8,9,10,11,12,13
//Список передаваемых пинов: A0,A1,A2,A3,2,3
//Список доп пинов питания 7,8 (В итоговой версии необходимо объединить на 5V, Gnd объединить)
RX:
#include
#include "nRF24L01.h"
#include "RF24.h"
#include
RF24 radio(9, 10); //Создать модуль на пинах 9 и 10
byte recieved_data[6]; //Массив принятых данных
byte XLP; //Значения левого стика ось X
byte YLP; //Значения левого стика ось Y
byte XRP; //Значения правого стика ось X
byte YRP; //Значения правого стика ось Y
int LBMP; //Значения ЛКМ
int RBMP; //Значения ПКМ
const int Sp = 30; //Скорость курсора (10,20,30,40,50,60,70) чем больше, тем медленне
byte address[][6] = {"1Node", "2Node", "3Node", "4Node", "5Node", "6Node"}; //возможные номера труб
void setup() {
Serial.begin(9600); //Открываем порт для связи с ПК
Mouse.begin();
radio.begin(); //Активировать модуль
radio.setAutoAck(1); // Режим подтверждения приёма, 1 вкл 0 выкл
radio.setRetries(0, 15); // Время между попыткой достучаться, число попыток)
radio.enableAckPayload(); // Разрешить отсылку данных в ответ на входящий сигнал
radio.setPayloadSize(32); // Размер пакета, в байтах
radio.openReadingPipe(1, address[0]); // Слушаем трубу 0
radio.setChannel(0x70); // Выбираем канал (в котором нет шумов!)
radio.setPALevel (RF24_PA_MAX); // Уровень мощности передатчика. На выбор RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH, RF24_PA_MAX
radio.setDataRate (RF24_250KBPS); // Скорость обмена. На выбор RF24_2MBPS, RF24_1MBPS, RF24_250KBPS должна быть одинакова на приёмнике и передатчике! Gри самой низкой скорости имеем самую высокую чувствительность и дальность!!
radio.powerUp(); // Начать работу
radio.startListening(); // Начинаем слушать эфир, мы приёмный модуль
}
void loop() {
byte pipeNo;
while ( radio.available(&pipeNo)) { // Есть входящие данные
radio.read(&recieved_data, sizeof(recieved_data)); // Читаем входящий сигнал
XLP = recieved_data[0]; //Читаем входящие данные оси X левого стика и записываем значение
YLP = recieved_data[1]; //Читаем входящие данные оси Y левого стика и записываем значение
XRP = recieved_data[2]; //Читаем входящие данные оси X правого стика и записываем значение
YRP = recieved_data[3]; //Читаем входящие данные оси Y правого стика и записываем значение
LBMP = recieved_data[4]; //Читаем входящие данные ЛКМ и записываем значение
RBMP = recieved_data[5]; //Читаем входящие данные ПКМ и записываем значение
}
int xLpos, yLpos;
int xRpos, yRpos;
//Фильтр XYL
if (XLP > 120 and XLP < 130)
xLpos = 0;
if (XLP >= 130)
xLpos = map(XLP, 130, 255, 0, 80);
if (XLP <= 120)
xLpos = map(XLP, 120, 0, 0, -80);
if (YLP > 120 and YLP < 130)
yLpos = 0;
if (YLP >= 130)
yLpos = map(YLP, 130, 255, 0, 80);
if (YLP <= 120)
yLpos = map(YLP, 120, 0, 0, -80);
//Фильтр XYR
if (XRP > 120 and XRP < 130)
xRpos = 0;
if (XRP >= 130)
xRpos = map(XRP, 130, 255, 0, 80);
if (XRP <= 120)
xRpos = map(XRP, 120, 0, 0, -80);
if (YRP > 120 and YRP < 130)
yRpos = 0;
if (YRP >= 130)
yRpos = map(YRP, 130, 255, 0, 80);
if (YRP <= 120)
yRpos = map(YRP, 120, 0, 0, -80);
//Управление курсором
Mouse.move(xRpos / Sp, yRpos / Sp);
if (LBMP) {
Mouse.press(MOUSE_LEFT);
} else {
Mouse.release(MOUSE_LEFT);
}
if (RBMP) {
Mouse.press(MOUSE_RIGHT);
} else {
Mouse.release(MOUSE_RIGHT);
}
/*//Отладка A0,A1,A2,A3
Serial.print(XLP);
Serial.print(":");
Serial.print(YLP);
Serial.print(":");
Serial.println(LBMP);
Serial.print("\n");
Serial.print(XRP);
Serial.print(":");
Serial.print(YRP);
Serial.print(":");
Serial.println(RBMP);
Serial.print("\n");
Serial.print(xRpos);
Serial.print(":");
Serial.print(yRpos);
delay(5);
*/
}
//Список занятых пинов: 9,10,14,15,16
//Список передаваемых пинов: A0,A1,A2,A3,2,3
//LBM-LeftButtonMouse(ЛКМ) RBM-RightButtonMouse(ПКМ)