mirror of
https://github.com/LuiCat/ArduinoTaikoController.git
synced 2024-11-27 16:10:51 +01:00
Nintendo Switch joycon support, sensitivity and enhanced refreshing interval
This commit is contained in:
parent
46bbd1c081
commit
fa7c5b371d
128
HIDReportData.h
Normal file
128
HIDReportData.h
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2017.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2017 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Constants for HID report item attributes.
|
||||
*
|
||||
* HID report item constants for report item attributes. Refer to the HID specification for
|
||||
* details on each flag's meaning when applied to an IN, OUT or FEATURE item.
|
||||
*/
|
||||
|
||||
/** \ingroup Group_HIDParser
|
||||
* \defgroup Group_HIDReportItemConst HID Report Descriptor Item Constants
|
||||
*
|
||||
* General HID constant definitions for HID Report Descriptor elements.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __HIDREPORTDATA_H__
|
||||
#define __HIDREPORTDATA_H__
|
||||
|
||||
#warning Modified LUFA header file. Remove the file if problematic.
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Macros: */
|
||||
#define HID_RI_DATA_SIZE_MASK 0x03
|
||||
#define HID_RI_TYPE_MASK 0x0C
|
||||
#define HID_RI_TAG_MASK 0xF0
|
||||
|
||||
#define HID_RI_TYPE_MAIN 0x00
|
||||
#define HID_RI_TYPE_GLOBAL 0x04
|
||||
#define HID_RI_TYPE_LOCAL 0x08
|
||||
|
||||
#define HID_RI_DATA_BITS_0 0x00
|
||||
#define HID_RI_DATA_BITS_8 0x01
|
||||
#define HID_RI_DATA_BITS_16 0x02
|
||||
#define HID_RI_DATA_BITS_32 0x03
|
||||
#define HID_RI_DATA_BITS(DataBits) HID_RI_DATA_BITS_ ## DataBits
|
||||
|
||||
#define _HID_RI_ENCODE_0(Data)
|
||||
#define _HID_RI_ENCODE_8(Data) , (Data & 0xFF)
|
||||
#define _HID_RI_ENCODE_16(Data) _HID_RI_ENCODE_8(Data) _HID_RI_ENCODE_8(Data >> 8)
|
||||
#define _HID_RI_ENCODE_32(Data) _HID_RI_ENCODE_16(Data) _HID_RI_ENCODE_16(Data >> 16)
|
||||
#define _HID_RI_ENCODE(DataBits, ...) _HID_RI_ENCODE_ ## DataBits(__VA_ARGS__)
|
||||
|
||||
#define _HID_RI_ENTRY(Type, Tag, DataBits, ...) (Type | Tag | HID_RI_DATA_BITS(DataBits)) _HID_RI_ENCODE(DataBits, (__VA_ARGS__))
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
/** \name HID Input, Output and Feature Report Descriptor Item Flags */
|
||||
//@{
|
||||
#define HID_IOF_CONSTANT (1 << 0)
|
||||
#define HID_IOF_DATA (0 << 0)
|
||||
#define HID_IOF_VARIABLE (1 << 1)
|
||||
#define HID_IOF_ARRAY (0 << 1)
|
||||
#define HID_IOF_RELATIVE (1 << 2)
|
||||
#define HID_IOF_ABSOLUTE (0 << 2)
|
||||
#define HID_IOF_WRAP (1 << 3)
|
||||
#define HID_IOF_NO_WRAP (0 << 3)
|
||||
#define HID_IOF_NON_LINEAR (1 << 4)
|
||||
#define HID_IOF_LINEAR (0 << 4)
|
||||
#define HID_IOF_NO_PREFERRED_STATE (1 << 5)
|
||||
#define HID_IOF_PREFERRED_STATE (0 << 5)
|
||||
#define HID_IOF_NULLSTATE (1 << 6)
|
||||
#define HID_IOF_NO_NULL_POSITION (0 << 6)
|
||||
#define HID_IOF_VOLATILE (1 << 7)
|
||||
#define HID_IOF_NON_VOLATILE (0 << 7)
|
||||
#define HID_IOF_BUFFERED_BYTES (1 << 8)
|
||||
#define HID_IOF_BITFIELD (0 << 8)
|
||||
//@}
|
||||
|
||||
/** \name HID Report Descriptor Item Macros */
|
||||
//@{
|
||||
#define HID_RI_INPUT(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_MAIN , 0x80, DataBits, __VA_ARGS__)
|
||||
#define HID_RI_OUTPUT(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_MAIN , 0x90, DataBits, __VA_ARGS__)
|
||||
#define HID_RI_COLLECTION(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_MAIN , 0xA0, DataBits, __VA_ARGS__)
|
||||
#define HID_RI_FEATURE(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_MAIN , 0xB0, DataBits, __VA_ARGS__)
|
||||
#define HID_RI_END_COLLECTION(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_MAIN , 0xC0, DataBits, __VA_ARGS__)
|
||||
#define HID_RI_USAGE_PAGE(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x00, DataBits, __VA_ARGS__)
|
||||
#define HID_RI_LOGICAL_MINIMUM(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x10, DataBits, __VA_ARGS__)
|
||||
#define HID_RI_LOGICAL_MAXIMUM(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x20, DataBits, __VA_ARGS__)
|
||||
#define HID_RI_PHYSICAL_MINIMUM(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x30, DataBits, __VA_ARGS__)
|
||||
#define HID_RI_PHYSICAL_MAXIMUM(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x40, DataBits, __VA_ARGS__)
|
||||
#define HID_RI_UNIT_EXPONENT(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x50, DataBits, __VA_ARGS__)
|
||||
#define HID_RI_UNIT(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x60, DataBits, __VA_ARGS__)
|
||||
#define HID_RI_REPORT_SIZE(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x70, DataBits, __VA_ARGS__)
|
||||
#define HID_RI_REPORT_ID(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x80, DataBits, __VA_ARGS__)
|
||||
#define HID_RI_REPORT_COUNT(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x90, DataBits, __VA_ARGS__)
|
||||
#define HID_RI_PUSH(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0xA0, DataBits, __VA_ARGS__)
|
||||
#define HID_RI_POP(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0xB0, DataBits, __VA_ARGS__)
|
||||
#define HID_RI_USAGE(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_LOCAL , 0x00, DataBits, __VA_ARGS__)
|
||||
#define HID_RI_USAGE_MINIMUM(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_LOCAL , 0x10, DataBits, __VA_ARGS__)
|
||||
#define HID_RI_USAGE_MAXIMUM(DataBits, ...) _HID_RI_ENTRY(HID_RI_TYPE_LOCAL , 0x20, DataBits, __VA_ARGS__)
|
||||
//@}
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif
|
||||
|
103
Joystick.cpp
Normal file
103
Joystick.cpp
Normal file
@ -0,0 +1,103 @@
|
||||
#include "Joystick.h"
|
||||
#include "HIDReportData.h"
|
||||
|
||||
/***
|
||||
* All enum, class and descriptor definitions are originally written by progmem in library Switch-Fightstick(https://github.com/progmem/Switch-Fightstick).
|
||||
* Original code can be found in:
|
||||
* progmem/Switch-Fightstick/Joystick.h
|
||||
* https://github.com/progmem/Switch-Fightstick/blob/master/Joystick.h
|
||||
***/
|
||||
|
||||
// Functions added to HID_ class
|
||||
// Don't forget to add definitions in HID.h, which is located at:
|
||||
// <arduino installation path>\hardware\arduino\avr\libraries\HID\src\
|
||||
|
||||
void HID_::PrependDescriptor(HIDSubDescriptor *node)
|
||||
{
|
||||
node->next = rootNode;
|
||||
rootNode = node;
|
||||
descriptorSize += node->length;
|
||||
}
|
||||
|
||||
int HID_::SendRaw(const void* data, int len)
|
||||
{
|
||||
return USB_Send(pluggedEndpoint | TRANSFER_RELEASE, data, len);
|
||||
}
|
||||
|
||||
/***
|
||||
* Descriptor modified from
|
||||
* progmem/Switch-Fightstick/Joystick.c
|
||||
* https://github.com/progmem/Switch-Fightstick/blob/master/Joystick.h
|
||||
***/
|
||||
|
||||
static const uint8_t _hidReportDescriptor[] PROGMEM = {
|
||||
HID_RI_USAGE_PAGE(8,1), /* Generic Desktop */
|
||||
HID_RI_USAGE(8,5), /* Joystick */
|
||||
HID_RI_COLLECTION(8,1), /* Application */
|
||||
// Report ID
|
||||
HID_RI_REPORT_ID(8,3),
|
||||
// Buttons (2 bytes)
|
||||
HID_RI_LOGICAL_MINIMUM(8,0),
|
||||
HID_RI_LOGICAL_MAXIMUM(8,1),
|
||||
HID_RI_PHYSICAL_MINIMUM(8,0),
|
||||
HID_RI_PHYSICAL_MAXIMUM(8,1),
|
||||
// The Switch will allow us to expand the original HORI descriptors to a full 16 buttons.
|
||||
// The Switch will make use of 14 of those buttons.
|
||||
HID_RI_REPORT_SIZE(8,1),
|
||||
HID_RI_REPORT_COUNT(8,16),
|
||||
HID_RI_USAGE_PAGE(8,9),
|
||||
HID_RI_USAGE_MINIMUM(8,1),
|
||||
HID_RI_USAGE_MAXIMUM(8,16),
|
||||
HID_RI_INPUT(8,2),
|
||||
// HAT Switch (1 nibble)
|
||||
HID_RI_USAGE_PAGE(8,1),
|
||||
HID_RI_LOGICAL_MAXIMUM(8,7),
|
||||
HID_RI_PHYSICAL_MAXIMUM(16,315),
|
||||
HID_RI_REPORT_SIZE(8,4),
|
||||
HID_RI_REPORT_COUNT(8,1),
|
||||
HID_RI_UNIT(8,20),
|
||||
HID_RI_USAGE(8,57),
|
||||
HID_RI_INPUT(8,66),
|
||||
// There's an additional nibble here that's utilized as part of the Switch Pro Controller.
|
||||
// I believe this -might- be separate U/D/L/R bits on the Switch Pro Controller, as they're utilized as four button descriptors on the Switch Pro Controller.
|
||||
HID_RI_UNIT(8,0),
|
||||
HID_RI_REPORT_COUNT(8,1),
|
||||
HID_RI_INPUT(8,1),
|
||||
// Joystick (4 bytes)
|
||||
HID_RI_LOGICAL_MAXIMUM(16,255),
|
||||
HID_RI_PHYSICAL_MAXIMUM(16,255),
|
||||
HID_RI_USAGE(8,48),
|
||||
HID_RI_USAGE(8,49),
|
||||
HID_RI_USAGE(8,50),
|
||||
HID_RI_USAGE(8,53),
|
||||
HID_RI_REPORT_SIZE(8,8),
|
||||
HID_RI_REPORT_COUNT(8,4),
|
||||
HID_RI_INPUT(8,2),
|
||||
// ??? Vendor Specific (1 byte)
|
||||
// This byte requires additional investigation.
|
||||
HID_RI_USAGE_PAGE(16,65280),
|
||||
HID_RI_USAGE(8,32),
|
||||
HID_RI_REPORT_COUNT(8,1),
|
||||
HID_RI_INPUT(8,2),
|
||||
// Output (8 bytes)
|
||||
// Original observation of this suggests it to be a mirror of the inputs that we sent.
|
||||
// The Switch requires us to have these descriptors available.
|
||||
HID_RI_USAGE(16,9761),
|
||||
HID_RI_REPORT_COUNT(8,8),
|
||||
HID_RI_OUTPUT(8,2),
|
||||
HID_RI_END_COLLECTION(0),
|
||||
};
|
||||
|
||||
Joystick_::Joystick_()
|
||||
{
|
||||
static HIDSubDescriptor node(_hidReportDescriptor, sizeof(_hidReportDescriptor));
|
||||
HID().PrependDescriptor(&node); // This descriptor need to be the first one so that the device can be recognized by Switch
|
||||
}
|
||||
|
||||
void Joystick_::sendState()
|
||||
{
|
||||
HID().SendRaw(this, 8); // No sending report ID. Switch doesn't deal with that properly.
|
||||
}
|
||||
|
||||
Joystick_ Joystick;
|
||||
|
61
Joystick.h
Normal file
61
Joystick.h
Normal file
@ -0,0 +1,61 @@
|
||||
#ifndef JOYSTICK_h
|
||||
#define JOYSTICK_h
|
||||
|
||||
#include <HID.h>
|
||||
|
||||
/***
|
||||
* All enum, class and descriptor definitions are originally written by progmem in library Switch-Fightstick(https://github.com/progmem/Switch-Fightstick).
|
||||
* Original code can be found in:
|
||||
* progmem/Switch-Fightstick/Joystick.h
|
||||
* https://github.com/progmem/Switch-Fightstick/blob/master/Joystick.h
|
||||
***/
|
||||
|
||||
// Enumeration for joystick buttons.
|
||||
typedef enum {
|
||||
SWITCH_BTN_NONE = 0x00,
|
||||
SWITCH_BTN_Y = 0x01,
|
||||
SWITCH_BTN_B = 0x02,
|
||||
SWITCH_BTN_A = 0x04,
|
||||
SWITCH_BTN_X = 0x08,
|
||||
SWITCH_BTN_L = 0x10,
|
||||
SWITCH_BTN_R = 0x20,
|
||||
SWITCH_BTN_ZL = 0x40,
|
||||
SWITCH_BTN_ZR = 0x80,
|
||||
SWITCH_BTN_SELECT = 0x100,
|
||||
SWITCH_BTN_START = 0x200,
|
||||
SWITCH_BTN_LCLICK = 0x400,
|
||||
SWITCH_BTN_RCLICK = 0x800,
|
||||
SWITCH_BTN_HOME = 0x1000,
|
||||
SWITCH_BTN_CAPTURE = 0x2000,
|
||||
} JoystickButtons_t;
|
||||
|
||||
// Enumeration for joystick hats.
|
||||
typedef enum {
|
||||
SWITCH_HAT_U = 0x00,
|
||||
SWITCH_HAT_UR = 0x01,
|
||||
SWITCH_HAT_R = 0x02,
|
||||
SWITCH_HAT_DR = 0x03,
|
||||
SWITCH_HAT_D = 0x04,
|
||||
SWITCH_HAT_DL = 0x05,
|
||||
SWITCH_HAT_L = 0x06,
|
||||
SWITCH_HAT_UL = 0x07,
|
||||
SWITCH_HAT_CENTER = 0x08,
|
||||
} JoystickHats_t;
|
||||
|
||||
struct Joystick_
|
||||
{
|
||||
uint16_t Button = SWITCH_BTN_NONE; // 16 buttons; see JoystickButtons_t for bit mapping
|
||||
uint8_t HAT = SWITCH_HAT_CENTER; // HAT switch; one nibble w/ unused nibble
|
||||
uint8_t LX = 128; // Left Stick X
|
||||
uint8_t LY = 128; // Left Stick Y
|
||||
uint8_t RX = 128; // Right Stick X
|
||||
uint8_t RY = 128; // Right Stick Y
|
||||
uint8_t VendorSpec = 0;
|
||||
|
||||
Joystick_();
|
||||
void sendState();
|
||||
};
|
||||
|
||||
extern Joystick_ Joystick;
|
||||
|
||||
#endif
|
24
LUFA_LICENSE
Normal file
24
LUFA_LICENSE
Normal file
@ -0,0 +1,24 @@
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
|
||||
|
||||
Permission to use, copy, modify, and distribute this software
|
||||
and its documentation for any purpose is hereby granted without
|
||||
fee, provided that the above copyright notice appear in all
|
||||
copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
21
Switch_Fightstick_LICENSE
Normal file
21
Switch_Fightstick_LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 @progmem
|
||||
|
||||
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.
|
@ -1,17 +1,46 @@
|
||||
#include <Keyboard.h>
|
||||
|
||||
//#define DEBUG_OUTPUT
|
||||
//#define DEBUG_OUTPUT_LIVE
|
||||
//#define ENABLE_KEYBOARD
|
||||
|
||||
const int min_threshold = 20;
|
||||
const long cd_length = 8000;
|
||||
const long cd_antireso_length = 8000;
|
||||
const float k_antireso = 0.85;
|
||||
const float k_decay = 0.96;
|
||||
#define ENABLE_NS_JOYSTICK
|
||||
|
||||
const int pin[4] = {A3, A0, A2, A1};
|
||||
const int key[4] = {'d', 'f', 'j', 'k'};
|
||||
#ifdef ENABLE_KEYBOARD
|
||||
#include <Keyboard.h>
|
||||
#endif
|
||||
|
||||
const int key_next[4] = {1, 3, 0, 2};
|
||||
#ifdef ENABLE_NS_JOYSTICK
|
||||
#include "Joystick.h"
|
||||
const int led_pin[4] = {8, 9, 10, 11};
|
||||
const int sensor_button[4] = {SWITCH_BTN_ZL, SWITCH_BTN_LCLICK, SWITCH_BTN_RCLICK, SWITCH_BTN_ZR};
|
||||
const int button[16] = {
|
||||
0 /*SWITCH_HAT_U*/, 0 /*SWITCH_HAT_R*/, 0 /*SWITCH_HAT_D*/, 0 /*SWITCH_HAT_L*/,
|
||||
SWITCH_BTN_X, SWITCH_BTN_A, SWITCH_BTN_B, SWITCH_BTN_Y,
|
||||
SWITCH_BTN_L, SWITCH_BTN_R, SWITCH_BTN_SELECT, SWITCH_BTN_START,
|
||||
SWITCH_BTN_CAPTURE, SWITCH_BTN_HOME, 0 /*Fn1*/, 0 /*Fn2*/
|
||||
};
|
||||
const int hat_mapping[16] = {
|
||||
SWITCH_HAT_CENTER, SWITCH_HAT_U, SWITCH_HAT_R, SWITCH_HAT_UR,
|
||||
SWITCH_HAT_D, SWITCH_HAT_CENTER, SWITCH_HAT_DR, SWITCH_HAT_R,
|
||||
SWITCH_HAT_L, SWITCH_HAT_UL, SWITCH_HAT_CENTER, SWITCH_HAT_U,
|
||||
SWITCH_HAT_DL, SWITCH_HAT_L, SWITCH_HAT_D, SWITCH_HAT_CENTER,
|
||||
};
|
||||
int button_state[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
int button_cd[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
#endif
|
||||
|
||||
const int min_threshold = 10;
|
||||
const long cd_length = 16000;
|
||||
const long cd_antireso_length = 16000;
|
||||
const float k_threshold = 1.5;
|
||||
const float k_antireso = 1.5;
|
||||
const float k_decay = 0.983;
|
||||
|
||||
const int pin[4] = {A0, A3, A1, A2};
|
||||
const int key[4] = {'d', '
|
||||
f', 'j', 'k'};
|
||||
const float sens[4] = {1.0, 1.0, 0.8, 0.8};
|
||||
|
||||
const int key_next[4] = {2, 0, 3, 1};
|
||||
|
||||
const long cd_stageselect = 200000;
|
||||
|
||||
@ -20,11 +49,16 @@ bool stageresult = false;
|
||||
|
||||
float threshold[4] = {20, 20, 20, 20};
|
||||
int raw[4] = {0, 0, 0, 0};
|
||||
int level[4] = {0, 0, 0, 0};
|
||||
float level[4] = {0, 0, 0, 0};
|
||||
long cd[4] = {0, 0, 0, 0};
|
||||
bool down[4] = {false, false, false, false};
|
||||
#ifdef ENABLE_NS_JOYSTICK
|
||||
bool pressed[4] = {false, false, false, false};
|
||||
int t0 = 0;
|
||||
int dt = 0, sdt = 0;
|
||||
#endif
|
||||
|
||||
typedef unsigned long time_t;
|
||||
time_t t0 = 0;
|
||||
time_t dt = 0, sdt = 0;
|
||||
|
||||
void sample() {
|
||||
int prev[4] = {raw[0], raw[1], raw[2], raw[3]};
|
||||
@ -33,20 +67,26 @@ void sample() {
|
||||
raw[2] = analogRead(pin[2]);
|
||||
raw[3] = analogRead(pin[3]);
|
||||
for (int i=0; i<4; ++i)
|
||||
level[i] = abs(raw[i] - prev[i]);
|
||||
level[i] = abs(raw[i] - prev[i]) * sens[i];
|
||||
}
|
||||
|
||||
void sampleSingle(int i) {
|
||||
int prev = raw[i];
|
||||
raw[i] = analogRead(pin[i]);
|
||||
level[i] = abs(raw[i] - prev);
|
||||
level[i] = abs(raw[i] - prev) * sens[i];
|
||||
}
|
||||
|
||||
void setup() {
|
||||
analogReference(DEFAULT); // use internal 1.1v as reference voltage
|
||||
pinMode(LED_BUILTIN, OUTPUT);
|
||||
digitalWrite(LED_BUILTIN, LOW);
|
||||
#ifdef ENABLE_NS_JOYSTICK
|
||||
for (int i = 0; i < 8; ++i) pinMode(i, INPUT_PULLUP);
|
||||
for (int i = 0; i < 4; ++i) { digitalWrite(led_pin[i], HIGH); pinMode(led_pin[i], OUTPUT); }
|
||||
#endif
|
||||
#ifdef ENABLE_KEYBOARD
|
||||
Keyboard.begin();
|
||||
#endif
|
||||
t0 = micros();
|
||||
Serial.begin(9600);
|
||||
}
|
||||
@ -78,32 +118,65 @@ void parseSerial() {
|
||||
}
|
||||
}
|
||||
|
||||
void loop_test() {
|
||||
sampleSingle(0);
|
||||
Serial.print(level[0]);
|
||||
Serial.print("\t");
|
||||
delayMicroseconds(500);
|
||||
sampleSingle(1);
|
||||
Serial.print(level[1]);
|
||||
Serial.print("\t");
|
||||
delayMicroseconds(500);
|
||||
sampleSingle(2);
|
||||
Serial.print(level[2]);
|
||||
Serial.print("\t");
|
||||
delayMicroseconds(500);
|
||||
sampleSingle(3);
|
||||
Serial.print(level[3]);
|
||||
Serial.println();
|
||||
delayMicroseconds(500);
|
||||
}
|
||||
|
||||
void loop_test2() {
|
||||
Serial.print(analogRead(pin[0]));
|
||||
Serial.print("\t");
|
||||
delayMicroseconds(500);
|
||||
Serial.print(analogRead(pin[1]));
|
||||
Serial.print("\t");
|
||||
delayMicroseconds(500);
|
||||
Serial.print(analogRead(pin[2]));
|
||||
Serial.print("\t");
|
||||
delayMicroseconds(500);
|
||||
Serial.print(analogRead(pin[3]));
|
||||
Serial.println();
|
||||
delayMicroseconds(500);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
//loop_test2(); return;
|
||||
|
||||
static int si = 0;
|
||||
|
||||
parseSerial();
|
||||
|
||||
int t1 = micros();
|
||||
time_t t1 = micros();
|
||||
dt = t1 - t0;
|
||||
sdt += dt;
|
||||
t0 = t1;
|
||||
|
||||
while (sdt >= 1000) {
|
||||
sdt -= 1000;
|
||||
for (int i = 0; i != 4; ++i)
|
||||
threshold[i] *= k_decay;
|
||||
}
|
||||
for (int i = 0; i != 4; ++i)
|
||||
threshold[i] *= k_decay;
|
||||
|
||||
for (int i = 0; i != 4; ++i) {
|
||||
if (cd[i] > 0) {
|
||||
cd[i] -= dt;
|
||||
if (cd[i] <= 0) {
|
||||
cd[i] = 0;
|
||||
if (pressed[i]) {
|
||||
#ifndef DEBUG_OUTPUT
|
||||
if (down[i]) {
|
||||
#ifdef ENABLE_KEYBOARD
|
||||
Keyboard.release(stageresult ? KEY_ESC : key[i]);
|
||||
#endif
|
||||
pressed[i] = false;
|
||||
down[i] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -121,15 +194,18 @@ void loop() {
|
||||
|
||||
if (i_max == si && level_max >= min_threshold) {
|
||||
if (cd[i_max] == 0) {
|
||||
if (!pressed[i_max]) {
|
||||
#ifndef DEBUG_OUTPUT
|
||||
if (!down[i_max]) {
|
||||
#ifdef ENABLE_KEYBOARD
|
||||
if (stageresult) {
|
||||
Keyboard.press(KEY_ESC);
|
||||
} else {
|
||||
Keyboard.press(key[i_max]);
|
||||
}
|
||||
#endif
|
||||
down[i_max] = true;
|
||||
#ifdef ENABLE_NS_JOYSTICK
|
||||
pressed[i_max] = true;
|
||||
#endif
|
||||
}
|
||||
for (int i = 0; i != 4; ++i)
|
||||
cd[i] = cd_antireso_length;
|
||||
@ -138,44 +214,102 @@ void loop() {
|
||||
float level_antireso = level_max * k_antireso;
|
||||
for (int i = 0; i != 4; ++i)
|
||||
threshold[i] = max(threshold[i], level_antireso);
|
||||
threshold[i_max] = (cd[i_max] == 0 ? level_max : level_max * 1.5);
|
||||
threshold[i_max] = level_max * k_threshold;
|
||||
sdt = 0;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_NS_JOYSTICK
|
||||
// 4x4 button scan, one row per cycle
|
||||
static int bi = 3;
|
||||
pinMode(bi+4, INPUT_PULLUP);
|
||||
bi = ((bi+1)&3);
|
||||
pinMode(bi+4, OUTPUT);
|
||||
digitalWrite(bi+4, LOW);
|
||||
|
||||
static time_t ct = 0;
|
||||
static int cc = 0;
|
||||
ct += dt;
|
||||
cc += 1;
|
||||
|
||||
int state;
|
||||
int* bs = button_state + (bi << 2);
|
||||
int* bc = button_cd + (bi << 2);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
state = (digitalRead(i) == LOW);
|
||||
//digitalWrite(led_pin[i], state ? LOW : HIGH);
|
||||
if (bc[i] != 0) {
|
||||
bc[i] -= ct;
|
||||
if (bc[i] < 0) bc[i] = 0;
|
||||
}
|
||||
if (state != bs[i] && bc[i] == 0) {
|
||||
bs[i] = state;
|
||||
bc[i] = 15000;
|
||||
}
|
||||
Joystick.Button |= (bs[i] ? button[(bi << 2) + i] : SWITCH_BTN_NONE);
|
||||
}
|
||||
|
||||
if (ct > 32000 || (ct > 8000 && (pressed[0] || pressed[1] || pressed[2] || pressed[3]))) {
|
||||
for (int i = 0; i < 4; ++i) { // Sensors
|
||||
Joystick.Button |= (pressed[i] ? sensor_button[i] : SWITCH_BTN_NONE);
|
||||
digitalWrite(led_pin[i], pressed[i] ? LOW : HIGH);
|
||||
}
|
||||
state = 0;
|
||||
for (int i = 0; i < 4; ++i) { // Buttons for hats
|
||||
state |= (button_state[i] ? 1 << i : 0);
|
||||
}
|
||||
Joystick.HAT = hat_mapping[state];
|
||||
Joystick.sendState();
|
||||
Joystick.Button = SWITCH_BTN_NONE;
|
||||
memset(pressed, 0, sizeof(pressed));
|
||||
//Serial.print(ct);
|
||||
//Serial.print('\t');
|
||||
Serial.println((float)ct/cc);
|
||||
ct = 0;
|
||||
cc = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_OUTPUT
|
||||
static bool printing = false;
|
||||
if (si == 0) {
|
||||
if (level[0]+level[1]+level[2]+level[3] >= min_threshold || cd[0] || cd[1] || cd[2] || cd[3]){
|
||||
Serial.print(level[0]);
|
||||
Serial.print("\t");
|
||||
Serial.print(level[1]);
|
||||
Serial.print("\t");
|
||||
Serial.print(level[2]);
|
||||
Serial.print("\t");
|
||||
Serial.print(level[3]);
|
||||
Serial.print("\t| ");
|
||||
Serial.print(cd[0] == 0 ? " " : pressed[0] ? "# " : "* ");
|
||||
Serial.print(cd[1] == 0 ? " " : pressed[1] ? "# " : "* ");
|
||||
Serial.print(cd[2] == 0 ? " " : pressed[2] ? "# " : "* ");
|
||||
Serial.print(cd[3] == 0 ? " " : pressed[3] ? "# " : "* ");
|
||||
Serial.print("|\t");
|
||||
Serial.print((int)threshold[0]);
|
||||
Serial.print("\t");
|
||||
Serial.print((int)threshold[1]);
|
||||
Serial.print("\t");
|
||||
Serial.print((int)threshold[2]);
|
||||
Serial.print("\t");
|
||||
Serial.print((int)threshold[3]);
|
||||
Serial.println();
|
||||
printing = true;
|
||||
}else if(printing){
|
||||
Serial.println("=============================================================================");
|
||||
printing = false;
|
||||
}
|
||||
#ifdef DEBUG_OUTPUT_LIVE
|
||||
if (true)
|
||||
#else
|
||||
if (threshold[0] > min_threshold || threshold[1] > min_threshold ||
|
||||
threshold[2] > min_threshold || threshold[3] > min_threshold)
|
||||
#endif
|
||||
{
|
||||
Serial.print(level[0], 1);
|
||||
Serial.print("\t");
|
||||
Serial.print(level[1], 1);
|
||||
Serial.print("\t");
|
||||
Serial.print(level[2], 1);
|
||||
Serial.print("\t");
|
||||
Serial.print(level[3], 1);
|
||||
Serial.print("\t| ");
|
||||
Serial.print(cd[0] == 0 ? " " : down[0] ? "# " : "* ");
|
||||
Serial.print(cd[1] == 0 ? " " : down[1] ? "# " : "* ");
|
||||
Serial.print(cd[2] == 0 ? " " : down[2] ? "# " : "* ");
|
||||
Serial.print(cd[3] == 0 ? " " : down[3] ? "# " : "* ");
|
||||
Serial.print("|\t");
|
||||
Serial.print(threshold[0], 1);
|
||||
Serial.print("\t");
|
||||
Serial.print(threshold[1], 1);
|
||||
Serial.print("\t");
|
||||
Serial.print(threshold[2], 1);
|
||||
Serial.print("\t");
|
||||
Serial.print(threshold[3], 1);
|
||||
Serial.println();
|
||||
printing = true;
|
||||
}else if(printing){
|
||||
Serial.println("=============================================================================");
|
||||
printing = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
sampleSingle(si);
|
||||
si = key_next[si];
|
||||
|
||||
long ddt = 300 - (micros() - t0);
|
||||
if(ddt > 3) delayMicroseconds(ddt);
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user