Arduino project

This commit is contained in:
2026-09-26 12:44:35 +03:00
parent 6ecd607f99
commit 1017189a16
43 changed files with 23437 additions and 0 deletions
+5
View File
@@ -0,0 +1,5 @@
.pio
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch
+10
View File
@@ -0,0 +1,10 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
],
"unwantedRecommendations": [
"ms-vscode.cpptools-extension-pack"
]
}
+37
View File
@@ -0,0 +1,37 @@
This directory is intended for project header files.
A header file is a file containing C declarations and macro definitions
to be shared between several project source files. You request the use of a
header file in your project source file (C, C++, etc) located in `src` folder
by including it, with the C preprocessing directive `#include'.
```src/main.c
#include "header.h"
int main (void)
{
...
}
```
Including a header file produces the same results as copying the header file
into each source file that needs it. Such copying would be time-consuming
and error-prone. With a header file, the related declarations appear
in only one place. If they need to be changed, they can be changed in one
place, and programs that include the header file will automatically use the
new version when next recompiled. The header file eliminates the labor of
finding and changing all the copies as well as the risk that a failure to
find one copy will result in inconsistencies within a program.
In C, the convention is to give header files names that end with `.h'.
Read more about using header files in official GCC documentation:
* Include Syntax
* Include Operation
* Once-Only Headers
* Computed Includes
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
+46
View File
@@ -0,0 +1,46 @@
This directory is intended for project specific (private) libraries.
PlatformIO will compile them to static libraries and link into the executable file.
The source code of each library should be placed in a separate directory
("lib/your_library_name/[Code]").
For example, see the structure of the following example libraries `Foo` and `Bar`:
|--lib
| |
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| | |- library.json (optional. for custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
| |
| |--Foo
| | |- Foo.c
| | |- Foo.h
| |
| |- README --> THIS FILE
|
|- platformio.ini
|--src
|- main.c
Example contents of `src/main.c` using Foo and Bar:
```
#include <Foo.h>
#include <Bar.h>
int main (void)
{
...
}
```
The PlatformIO Library Dependency Finder will find automatically dependent
libraries by scanning project source files.
More information about PlatformIO Library Dependency Finder
- https://docs.platformio.org/page/librarymanager/ldf.html
+31
View File
@@ -0,0 +1,31 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:uno]
platform = atmelavr
;board = uno
board = sparkfun_promicro16
framework = arduino
lib_deps =
# --- БИБЛИОТЕКИ ДЛЯ ТЕКУЩЕГО МАКРОПАДА (ЛЕГКОВЕСНЫЕ) ---
gyverlibs/GyverOLED@^1.6.4 ; Быстрая и экономная библиотека для монохромных OLED-дисплеев (SSD1306/SSH1106). Идеальна для Arduino Uno/Pro Micro.
gyverlibs/GyverEncoder@^4.10 ; Опрос вращения и кликов энкодера с аппаратной фильтрацией дребезга контактов.
gyverlibs/EncButton ; Твоя новая библиотека для удобного опроса 3 настроечных кнопок (держит клики, удержания, многократные нажатия).
# --- ЭКОСИСТЕМА ADAFRUIT ДЛЯ СТАРЫХ И НОВЫХ МОНОХРОМНЫХ ЭКРАНОВ ---
adafruit/Adafruit GFX Library @ ^1.11.9 ; Базовое "графическое ядро" от Adafruit. Содержит логику рисования линий, кругов, шрифтов. Нужна как фундамент для других библиотек Adafruit.
adafruit/Adafruit SSD1306 @ ^2.5.9 ; Альтернативная (более тяжелая, чем у Гайвера) библиотека для OLED 128x32/128x64. Работает строго в связке с Adafruit GFX.
adafruit/Adafruit MCP4725 @ ^2.0.2
# --- БИБЛИОТЕКИ ДЛЯ ЦВЕТНЫХ ДИСПЛЕЕВ (НА БУДУЩЕЕ) ---
# (Строка adafruit/Adafruit GFX Library дублировалась, одну можно будет потом убрать)
adafruit/Adafruit ST7735 and ST7789 Library @ ^1.10.4 ; Библиотека для цветных TFT-экранчиков, работающих по SPI. Как раз подойдет для запуска дисплея с твоей фотографии.
olikraus/Ucglib @ ^1.5.2 ; Мощная графическая библиотека для цветных TFT-дисплеев через SPI. Главный плюс — красивые шрифты и высокая скорость отрисовки геометрических фигур.
+214
View File
@@ -0,0 +1,214 @@
/*
Keyboard.cpp
Copyright (c) 2015, Arduino LLC
Original code (pre-library): Copyright (c) 2011, Peter Barrett
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "Keyboard.h"
#include "KeyboardLayout.h"
#if defined(_USING_HID)
//================================================================================
//================================================================================
// Keyboard
static const uint8_t _hidReportDescriptor[] PROGMEM = {
// Keyboard
0x05, 0x01, // USAGE_PAGE (Generic Desktop) // 47
0x09, 0x06, // USAGE (Keyboard)
0xa1, 0x01, // COLLECTION (Application)
0x85, 0x02, // REPORT_ID (2)
0x05, 0x07, // USAGE_PAGE (Keyboard)
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x08, // REPORT_COUNT (8)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x08, // REPORT_SIZE (8)
0x81, 0x03, // INPUT (Cnst,Var,Abs)
0x95, 0x06, // REPORT_COUNT (6)
0x75, 0x08, // REPORT_SIZE (8)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x73, // LOGICAL_MAXIMUM (115)
0x05, 0x07, // USAGE_PAGE (Keyboard)
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
0x29, 0x73, // USAGE_MAXIMUM (Keyboard Application)
0x81, 0x00, // INPUT (Data,Ary,Abs)
0xc0, // END_COLLECTION
};
Keyboard_::Keyboard_(void)
{
static HIDSubDescriptor node(_hidReportDescriptor, sizeof(_hidReportDescriptor));
HID().AppendDescriptor(&node);
_asciimap = KeyboardLayout_en_US;
}
void Keyboard_::begin(const uint8_t *layout)
{
_asciimap = layout;
}
void Keyboard_::end(void)
{
}
void Keyboard_::sendReport(KeyReport* keys)
{
HID().SendReport(2,keys,sizeof(KeyReport));
}
uint8_t USBPutChar(uint8_t c);
// press() adds the specified key (printing, non-printing, or modifier)
// to the persistent key report and sends the report. Because of the way
// USB HID works, the host acts like the key remains pressed until we
// call release(), releaseAll(), or otherwise clear the report and resend.
size_t Keyboard_::press(uint8_t k)
{
uint8_t i;
if (k >= 136) { // it's a non-printing key (not a modifier)
k = k - 136;
} else if (k >= 128) { // it's a modifier key
_keyReport.modifiers |= (1<<(k-128));
k = 0;
} else { // it's a printing key
k = pgm_read_byte(_asciimap + k);
if (!k) {
setWriteError();
return 0;
}
if ((k & ALT_GR) == ALT_GR) {
_keyReport.modifiers |= 0x40; // AltGr = right Alt
k &= 0x3F;
} else if ((k & SHIFT) == SHIFT) {
_keyReport.modifiers |= 0x02; // the left shift modifier
k &= 0x7F;
}
if (k == ISO_REPLACEMENT) {
k = ISO_KEY;
}
}
// Add k to the key report only if it's not already present
// and if there is an empty slot.
if (_keyReport.keys[0] != k && _keyReport.keys[1] != k &&
_keyReport.keys[2] != k && _keyReport.keys[3] != k &&
_keyReport.keys[4] != k && _keyReport.keys[5] != k) {
for (i=0; i<6; i++) {
if (_keyReport.keys[i] == 0x00) {
_keyReport.keys[i] = k;
break;
}
}
if (i == 6) {
setWriteError();
return 0;
}
}
sendReport(&_keyReport);
return 1;
}
// release() takes the specified key out of the persistent key report and
// sends the report. This tells the OS the key is no longer pressed and that
// it shouldn't be repeated any more.
size_t Keyboard_::release(uint8_t k)
{
uint8_t i;
if (k >= 136) { // it's a non-printing key (not a modifier)
k = k - 136;
} else if (k >= 128) { // it's a modifier key
_keyReport.modifiers &= ~(1<<(k-128));
k = 0;
} else { // it's a printing key
k = pgm_read_byte(_asciimap + k);
if (!k) {
return 0;
}
if ((k & ALT_GR) == ALT_GR) {
_keyReport.modifiers &= ~(0x40); // AltGr = right Alt
k &= 0x3F;
} else if ((k & SHIFT) == SHIFT) {
_keyReport.modifiers &= ~(0x02); // the left shift modifier
k &= 0x7F;
}
if (k == ISO_REPLACEMENT) {
k = ISO_KEY;
}
}
// Test the key report to see if k is present. Clear it if it exists.
// Check all positions in case the key is present more than once (which it shouldn't be)
for (i=0; i<6; i++) {
if (0 != k && _keyReport.keys[i] == k) {
_keyReport.keys[i] = 0x00;
}
}
sendReport(&_keyReport);
return 1;
}
void Keyboard_::releaseAll(void)
{
_keyReport.keys[0] = 0;
_keyReport.keys[1] = 0;
_keyReport.keys[2] = 0;
_keyReport.keys[3] = 0;
_keyReport.keys[4] = 0;
_keyReport.keys[5] = 0;
_keyReport.modifiers = 0;
sendReport(&_keyReport);
}
size_t Keyboard_::write(uint8_t c)
{
uint8_t p = press(c); // Keydown
release(c); // Keyup
return p; // just return the result of press() since release() almost always returns 1
}
size_t Keyboard_::write(const uint8_t *buffer, size_t size) {
size_t n = 0;
while (size--) {
if (*buffer != '\r') {
if (write(*buffer)) {
n++;
} else {
break;
}
}
buffer++;
}
return n;
}
Keyboard_ Keyboard;
#endif
+151
View File
@@ -0,0 +1,151 @@
/*
Keyboard.h
Copyright (c) 2015, Arduino LLC
Original code (pre-library): Copyright (c) 2011, Peter Barrett
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef KEYBOARD_h
#define KEYBOARD_h
#include "HID.h"
#if !defined(_USING_HID)
#warning "Using legacy HID core (non pluggable)"
#else
//================================================================================
//================================================================================
// Keyboard
// Modifiers
#define KEY_LEFT_CTRL 0x80
#define KEY_LEFT_SHIFT 0x81
#define KEY_LEFT_ALT 0x82
#define KEY_LEFT_GUI 0x83
#define KEY_RIGHT_CTRL 0x84
#define KEY_RIGHT_SHIFT 0x85
#define KEY_RIGHT_ALT 0x86
#define KEY_RIGHT_GUI 0x87
// Misc keys
#define KEY_UP_ARROW 0xDA
#define KEY_DOWN_ARROW 0xD9
#define KEY_LEFT_ARROW 0xD8
#define KEY_RIGHT_ARROW 0xD7
#define KEY_BACKSPACE 0xB2
#define KEY_TAB 0xB3
#define KEY_RETURN 0xB0
#define KEY_MENU 0xED // "Keyboard Application" in USB standard
#define KEY_ESC 0xB1
#define KEY_INSERT 0xD1
#define KEY_DELETE 0xD4
#define KEY_PAGE_UP 0xD3
#define KEY_PAGE_DOWN 0xD6
#define KEY_HOME 0xD2
#define KEY_END 0xD5
#define KEY_CAPS_LOCK 0xC1
#define KEY_PRINT_SCREEN 0xCE // Print Screen / SysRq
#define KEY_SCROLL_LOCK 0xCF
#define KEY_PAUSE 0xD0 // Pause / Break
// Numeric keypad
#define KEY_NUM_LOCK 0xDB
#define KEY_KP_SLASH 0xDC
#define KEY_KP_ASTERISK 0xDD
#define KEY_KP_MINUS 0xDE
#define KEY_KP_PLUS 0xDF
#define KEY_KP_ENTER 0xE0
#define KEY_KP_1 0xE1
#define KEY_KP_2 0xE2
#define KEY_KP_3 0xE3
#define KEY_KP_4 0xE4
#define KEY_KP_5 0xE5
#define KEY_KP_6 0xE6
#define KEY_KP_7 0xE7
#define KEY_KP_8 0xE8
#define KEY_KP_9 0xE9
#define KEY_KP_0 0xEA
#define KEY_KP_DOT 0xEB
// Function keys
#define KEY_F1 0xC2
#define KEY_F2 0xC3
#define KEY_F3 0xC4
#define KEY_F4 0xC5
#define KEY_F5 0xC6
#define KEY_F6 0xC7
#define KEY_F7 0xC8
#define KEY_F8 0xC9
#define KEY_F9 0xCA
#define KEY_F10 0xCB
#define KEY_F11 0xCC
#define KEY_F12 0xCD
#define KEY_F13 0xF0
#define KEY_F14 0xF1
#define KEY_F15 0xF2
#define KEY_F16 0xF3
#define KEY_F17 0xF4
#define KEY_F18 0xF5
#define KEY_F19 0xF6
#define KEY_F20 0xF7
#define KEY_F21 0xF8
#define KEY_F22 0xF9
#define KEY_F23 0xFA
#define KEY_F24 0xFB
// Supported keyboard layouts
extern const uint8_t KeyboardLayout_de_DE[];
extern const uint8_t KeyboardLayout_en_US[];
extern const uint8_t KeyboardLayout_es_ES[];
extern const uint8_t KeyboardLayout_fr_FR[];
extern const uint8_t KeyboardLayout_it_IT[];
extern const uint8_t KeyboardLayout_pt_PT[];
extern const uint8_t KeyboardLayout_sv_SE[];
extern const uint8_t KeyboardLayout_da_DK[];
extern const uint8_t KeyboardLayout_hu_HU[];
// Low level key report: up to 6 keys and shift, ctrl etc at once
typedef struct
{
uint8_t modifiers;
uint8_t reserved;
uint8_t keys[6];
} KeyReport;
class Keyboard_ : public Print
{
private:
KeyReport _keyReport;
const uint8_t *_asciimap;
void sendReport(KeyReport* keys);
public:
Keyboard_(void);
void begin(const uint8_t *layout = KeyboardLayout_en_US);
void end(void);
size_t write(uint8_t k);
size_t write(const uint8_t *buffer, size_t size);
size_t press(uint8_t k);
size_t release(uint8_t k);
void releaseAll(void);
};
extern Keyboard_ Keyboard;
#endif
#endif
@@ -0,0 +1,67 @@
/*
KeyboardLayout.h
This file is not part of the public API. It is meant to be included
only in Keyboard.cpp and the keyboard layout files. Layout files map
ASCII character codes to keyboard scan codes (technically, to USB HID
Usage codes), possibly altered by the SHIFT or ALT_GR modifiers.
Non-ACSII characters (anything outside the 7-bit range NUL..DEL) are
not supported.
== Creating your own layout ==
In order to create your own layout file, copy an existing layout that
is similar to yours, then modify it to use the correct keys. The
layout is an array in ASCII order. Each entry contains a scan code,
possibly modified by "|SHIFT" or "|ALT_GR", as in this excerpt from
the Italian layout:
0x35, // bslash
0x30|ALT_GR, // ]
0x2e|SHIFT, // ^
Do not change the control characters (those before scan code 0x2c,
corresponding to space). Do not attempt to grow the table past DEL. Do
not use both SHIFT and ALT_GR on the same character: this is not
supported. Unsupported characters should have 0x00 as scan code.
For a keyboard with an ISO physical layout, use the scan codes below:
+---+---+---+---+---+---+---+---+---+---+---+---+---+-------+
|35 |1e |1f |20 |21 |22 |23 |24 |25 |26 |27 |2d |2e |BackSp |
+---+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-----+
| Tab |14 |1a |08 |15 |17 |1c |18 |0c |12 |13 |2f |30 | Ret |
+-----++--++--++--++--++--++--++--++--++--++--++--++--++ |
|CapsL |04 |16 |07 |09 |0a |0b |0d |0e |0f |33 |34 |31 | |
+----+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+---+----+
|Shi.|32 |1d |1b |06 |19 |05 |11 |10 |36 |37 |38 | Shift |
+----+---++--+-+-+---+---+---+---+---+--++---+---++----+----+
|Ctrl|Win |Alt | |AlGr|Win |Menu|Ctrl|
+----+----+----+------------------------+----+----+----+----+
The ANSI layout is identical except that key 0x31 is above (rather
than next to) Return, and there is not key 0x32.
Give a unique name to the layout array, then declare it in Keyboard.h
with a line of the form:
extern const uint8_t KeyboardLayout_xx_YY[];
== Encoding details ==
All scan codes are less than 0x80, which makes bit 7 available to
signal that a modifier (Shift or AltGr) is needed to generate the
character. With only one exception, keys that are used with modifiers
have scan codes that are less than 0x40. This makes bit 6 available
to signal whether the modifier is Shift or AltGr. The exception is
0x64, the key next next to Left Shift on the ISO layout (and absent
from the ANSI layout). We handle it by replacing its value by 0x32 in
the layout arrays.
*/
#include <Arduino.h>
#define SHIFT 0x80
#define ALT_GR 0xc0
#define ISO_KEY 0x64
#define ISO_REPLACEMENT 0x32
@@ -0,0 +1,138 @@
/*
* Danish keyboard layout.
*/
#include "KeyboardLayout.h"
extern const uint8_t KeyboardLayout_da_DK[128] PROGMEM =
{
0x00, // NUL
0x00, // SOH
0x00, // STX
0x00, // ETX
0x00, // EOT
0x00, // ENQ
0x00, // ACK
0x00, // BEL
0x2a, // BS Backspace
0x2b, // TAB Tab
0x28, // LF Enter
0x00, // VT
0x00, // FF
0x00, // CR
0x00, // SO
0x00, // SI
0x00, // DEL
0x00, // DC1
0x00, // DC2
0x00, // DC3
0x00, // DC4
0x00, // NAK
0x00, // SYN
0x00, // ETB
0x00, // CAN
0x00, // EM
0x00, // SUB
0x00, // ESC
0x00, // FS
0x00, // GS
0x00, // RS
0x00, // US
0x2c, // ' '
0x1e|SHIFT, // !
0x1f|SHIFT, // "
0x20|SHIFT, // #
0x21|ALT_GR, // $
0x22|SHIFT, // %
0x23|SHIFT, // &
0x31, // '
0x25|SHIFT, // (
0x26|SHIFT, // )
0x31|SHIFT, // *
0x2d, // +
0x36, // ,
0x38, // -
0x37, // .
0x24|SHIFT, // /
0x27, // 0
0x1e, // 1
0x1f, // 2
0x20, // 3
0x21, // 4
0x22, // 5
0x23, // 6
0x24, // 7
0x25, // 8
0x26, // 9
0x37|SHIFT, // :
0x36|SHIFT, // ;
0x32, // <
0x27|SHIFT, // =
0x32|SHIFT, // >
0x2d|SHIFT, // ?
0x1f|ALT_GR, // @
0x04|SHIFT, // A
0x05|SHIFT, // B
0x06|SHIFT, // C
0x07|SHIFT, // D
0x08|SHIFT, // E
0x09|SHIFT, // F
0x0a|SHIFT, // G
0x0b|SHIFT, // H
0x0c|SHIFT, // I
0x0d|SHIFT, // J
0x0e|SHIFT, // K
0x0f|SHIFT, // L
0x10|SHIFT, // M
0x11|SHIFT, // N
0x12|SHIFT, // O
0x13|SHIFT, // P
0x14|SHIFT, // Q
0x15|SHIFT, // R
0x16|SHIFT, // S
0x17|SHIFT, // T
0x18|SHIFT, // U
0x19|SHIFT, // V
0x1a|SHIFT, // W
0x1b|SHIFT, // X
0x1c|SHIFT, // Y
0x1d|SHIFT, // Z
0x25|ALT_GR, // [
0x32|ALT_GR, // bslash
0x26|ALT_GR, // ]
0x00, // ^ not supported (requires dead key + space)
0x38|SHIFT, // _
0x00, // ` not supported (requires dead key + space)
0x04, // a
0x05, // b
0x06, // c
0x07, // d
0x08, // e
0x09, // f
0x0a, // g
0x0b, // h
0x0c, // i
0x0d, // j
0x0e, // k
0x0f, // l
0x10, // m
0x11, // n
0x12, // o
0x13, // p
0x14, // q
0x15, // r
0x16, // s
0x17, // t
0x18, // u
0x19, // v
0x1a, // w
0x1b, // x
0x1c, // y
0x1d, // z
0x24|ALT_GR, // {
0x2e|ALT_GR, // |
0x27|ALT_GR, // }
0x00, // ~ not supported (requires dead key + space)
0x00 // DEL
};
@@ -0,0 +1,138 @@
/*
* German keyboard layout.
*/
#include "KeyboardLayout.h"
extern const uint8_t KeyboardLayout_de_DE[128] PROGMEM =
{
0x00, // NUL
0x00, // SOH
0x00, // STX
0x00, // ETX
0x00, // EOT
0x00, // ENQ
0x00, // ACK
0x00, // BEL
0x2a, // BS Backspace
0x2b, // TAB Tab
0x28, // LF Enter
0x00, // VT
0x00, // FF
0x00, // CR
0x00, // SO
0x00, // SI
0x00, // DEL
0x00, // DC1
0x00, // DC2
0x00, // DC3
0x00, // DC4
0x00, // NAK
0x00, // SYN
0x00, // ETB
0x00, // CAN
0x00, // EM
0x00, // SUB
0x00, // ESC
0x00, // FS
0x00, // GS
0x00, // RS
0x00, // US
0x2c, // ' '
0x1e|SHIFT, // !
0x1f|SHIFT, // "
0x31, // #
0x21|SHIFT, // $
0x22|SHIFT, // %
0x23|SHIFT, // &
0x31|SHIFT, // '
0x25|SHIFT, // (
0x26|SHIFT, // )
0x30|SHIFT, // *
0x30, // +
0x36, // ,
0x38, // -
0x37, // .
0x24|SHIFT, // /
0x27, // 0
0x1e, // 1
0x1f, // 2
0x20, // 3
0x21, // 4
0x22, // 5
0x23, // 6
0x24, // 7
0x25, // 8
0x26, // 9
0x37|SHIFT, // :
0x36|SHIFT, // ;
0x32, // <
0x27|SHIFT, // =
0x32|SHIFT, // >
0x2d|SHIFT, // ?
0x14|ALT_GR, // @
0x04|SHIFT, // A
0x05|SHIFT, // B
0x06|SHIFT, // C
0x07|SHIFT, // D
0x08|SHIFT, // E
0x09|SHIFT, // F
0x0a|SHIFT, // G
0x0b|SHIFT, // H
0x0c|SHIFT, // I
0x0d|SHIFT, // J
0x0e|SHIFT, // K
0x0f|SHIFT, // L
0x10|SHIFT, // M
0x11|SHIFT, // N
0x12|SHIFT, // O
0x13|SHIFT, // P
0x14|SHIFT, // Q
0x15|SHIFT, // R
0x16|SHIFT, // S
0x17|SHIFT, // T
0x18|SHIFT, // U
0x19|SHIFT, // V
0x1a|SHIFT, // W
0x1b|SHIFT, // X
0x1d|SHIFT, // Y
0x1c|SHIFT, // Z
0x25|ALT_GR, // [
0x2d|ALT_GR, // bslash
0x26|ALT_GR, // ]
0x00, // ^ not supported (requires dead key + space)
0x38|SHIFT, // _
0x00, // ` not supported (requires dead key + space)
0x04, // a
0x05, // b
0x06, // c
0x07, // d
0x08, // e
0x09, // f
0x0a, // g
0x0b, // h
0x0c, // i
0x0d, // j
0x0e, // k
0x0f, // l
0x10, // m
0x11, // n
0x12, // o
0x13, // p
0x14, // q
0x15, // r
0x16, // s
0x17, // t
0x18, // u
0x19, // v
0x1a, // w
0x1b, // x
0x1d, // y
0x1c, // z
0x24|ALT_GR, // {
0x32|ALT_GR, // |
0x27|ALT_GR, // }
0x30|ALT_GR, // ~
0x00 // DEL
};
@@ -0,0 +1,138 @@
/*
* Standard US keyboard layout.
*/
#include "KeyboardLayout.h"
extern const uint8_t KeyboardLayout_en_US[128] PROGMEM =
{
0x00, // NUL
0x00, // SOH
0x00, // STX
0x00, // ETX
0x00, // EOT
0x00, // ENQ
0x00, // ACK
0x00, // BEL
0x2a, // BS Backspace
0x2b, // TAB Tab
0x28, // LF Enter
0x00, // VT
0x00, // FF
0x00, // CR
0x00, // SO
0x00, // SI
0x00, // DEL
0x00, // DC1
0x00, // DC2
0x00, // DC3
0x00, // DC4
0x00, // NAK
0x00, // SYN
0x00, // ETB
0x00, // CAN
0x00, // EM
0x00, // SUB
0x00, // ESC
0x00, // FS
0x00, // GS
0x00, // RS
0x00, // US
0x2c, // ' '
0x1e|SHIFT, // !
0x34|SHIFT, // "
0x20|SHIFT, // #
0x21|SHIFT, // $
0x22|SHIFT, // %
0x24|SHIFT, // &
0x34, // '
0x26|SHIFT, // (
0x27|SHIFT, // )
0x25|SHIFT, // *
0x2e|SHIFT, // +
0x36, // ,
0x2d, // -
0x37, // .
0x38, // /
0x27, // 0
0x1e, // 1
0x1f, // 2
0x20, // 3
0x21, // 4
0x22, // 5
0x23, // 6
0x24, // 7
0x25, // 8
0x26, // 9
0x33|SHIFT, // :
0x33, // ;
0x36|SHIFT, // <
0x2e, // =
0x37|SHIFT, // >
0x38|SHIFT, // ?
0x1f|SHIFT, // @
0x04|SHIFT, // A
0x05|SHIFT, // B
0x06|SHIFT, // C
0x07|SHIFT, // D
0x08|SHIFT, // E
0x09|SHIFT, // F
0x0a|SHIFT, // G
0x0b|SHIFT, // H
0x0c|SHIFT, // I
0x0d|SHIFT, // J
0x0e|SHIFT, // K
0x0f|SHIFT, // L
0x10|SHIFT, // M
0x11|SHIFT, // N
0x12|SHIFT, // O
0x13|SHIFT, // P
0x14|SHIFT, // Q
0x15|SHIFT, // R
0x16|SHIFT, // S
0x17|SHIFT, // T
0x18|SHIFT, // U
0x19|SHIFT, // V
0x1a|SHIFT, // W
0x1b|SHIFT, // X
0x1c|SHIFT, // Y
0x1d|SHIFT, // Z
0x2f, // [
0x31, // bslash
0x30, // ]
0x23|SHIFT, // ^
0x2d|SHIFT, // _
0x35, // `
0x04, // a
0x05, // b
0x06, // c
0x07, // d
0x08, // e
0x09, // f
0x0a, // g
0x0b, // h
0x0c, // i
0x0d, // j
0x0e, // k
0x0f, // l
0x10, // m
0x11, // n
0x12, // o
0x13, // p
0x14, // q
0x15, // r
0x16, // s
0x17, // t
0x18, // u
0x19, // v
0x1a, // w
0x1b, // x
0x1c, // y
0x1d, // z
0x2f|SHIFT, // {
0x31|SHIFT, // |
0x30|SHIFT, // }
0x35|SHIFT, // ~
0x00 // DEL
};
@@ -0,0 +1,138 @@
/*
* Spanish keyboard layout.
*/
#include "KeyboardLayout.h"
extern const uint8_t KeyboardLayout_es_ES[128] PROGMEM =
{
0x00, // NUL
0x00, // SOH
0x00, // STX
0x00, // ETX
0x00, // EOT
0x00, // ENQ
0x00, // ACK
0x00, // BEL
0x2a, // BS Backspace
0x2b, // TAB Tab
0x28, // LF Enter
0x00, // VT
0x00, // FF
0x00, // CR
0x00, // SO
0x00, // SI
0x00, // DEL
0x00, // DC1
0x00, // DC2
0x00, // DC3
0x00, // DC4
0x00, // NAK
0x00, // SYN
0x00, // ETB
0x00, // CAN
0x00, // EM
0x00, // SUB
0x00, // ESC
0x00, // FS
0x00, // GS
0x00, // RS
0x00, // US
0x2c, // ' '
0x1e|SHIFT, // !
0x1f|SHIFT, // "
0x20|ALT_GR, // #
0x21|SHIFT, // $
0x22|SHIFT, // %
0x23|SHIFT, // &
0x2d, // '
0x25|SHIFT, // (
0x26|SHIFT, // )
0x30|SHIFT, // *
0x30, // +
0x36, // ,
0x38, // -
0x37, // .
0x24|SHIFT, // /
0x27, // 0
0x1e, // 1
0x1f, // 2
0x20, // 3
0x21, // 4
0x22, // 5
0x23, // 6
0x24, // 7
0x25, // 8
0x26, // 9
0x37|SHIFT, // :
0x36|SHIFT, // ;
0x32, // <
0x27|SHIFT, // =
0x32|SHIFT, // >
0x2d|SHIFT, // ?
0x1f|ALT_GR, // @
0x04|SHIFT, // A
0x05|SHIFT, // B
0x06|SHIFT, // C
0x07|SHIFT, // D
0x08|SHIFT, // E
0x09|SHIFT, // F
0x0a|SHIFT, // G
0x0b|SHIFT, // H
0x0c|SHIFT, // I
0x0d|SHIFT, // J
0x0e|SHIFT, // K
0x0f|SHIFT, // L
0x10|SHIFT, // M
0x11|SHIFT, // N
0x12|SHIFT, // O
0x13|SHIFT, // P
0x14|SHIFT, // Q
0x15|SHIFT, // R
0x16|SHIFT, // S
0x17|SHIFT, // T
0x18|SHIFT, // U
0x19|SHIFT, // V
0x1a|SHIFT, // W
0x1b|SHIFT, // X
0x1c|SHIFT, // Y
0x1d|SHIFT, // Z
0x2f|ALT_GR, // [
0x35|ALT_GR, // bslash
0x30|ALT_GR, // ]
0x00, // ^ not supported (requires dead key + space)
0x38|SHIFT, // _
0x00, // ` not supported (requires dead key + space)
0x04, // a
0x05, // b
0x06, // c
0x07, // d
0x08, // e
0x09, // f
0x0a, // g
0x0b, // h
0x0c, // i
0x0d, // j
0x0e, // k
0x0f, // l
0x10, // m
0x11, // n
0x12, // o
0x13, // p
0x14, // q
0x15, // r
0x16, // s
0x17, // t
0x18, // u
0x19, // v
0x1a, // w
0x1b, // x
0x1c, // y
0x1d, // z
0x34|ALT_GR, // {
0x1e|ALT_GR, // |
0x31|ALT_GR, // }
0x00, // ~ not supported (requires dead key + space)
0x00 // DEL
};
@@ -0,0 +1,138 @@
/*
* Traditional (not AFNOR) French keyboard layout.
*/
#include "KeyboardLayout.h"
extern const uint8_t KeyboardLayout_fr_FR[128] PROGMEM =
{
0x00, // NUL
0x00, // SOH
0x00, // STX
0x00, // ETX
0x00, // EOT
0x00, // ENQ
0x00, // ACK
0x00, // BEL
0x2a, // BS Backspace
0x2b, // TAB Tab
0x28, // LF Enter
0x00, // VT
0x00, // FF
0x00, // CR
0x00, // SO
0x00, // SI
0x00, // DEL
0x00, // DC1
0x00, // DC2
0x00, // DC3
0x00, // DC4
0x00, // NAK
0x00, // SYN
0x00, // ETB
0x00, // CAN
0x00, // EM
0x00, // SUB
0x00, // ESC
0x00, // FS
0x00, // GS
0x00, // RS
0x00, // US
0x2c, // ' '
0x38, // !
0x20, // "
0x20|ALT_GR, // #
0x30, // $
0x34|SHIFT, // %
0x1E, // &
0x21, // '
0x22, // (
0x2d, // )
0x31, // *
0x2e|SHIFT, // +
0x10, // ,
0x23, // -
0x36|SHIFT, // .
0x37|SHIFT, // /
0x27|SHIFT, // 0
0x1e|SHIFT, // 1
0x1f|SHIFT, // 2
0x20|SHIFT, // 3
0x21|SHIFT, // 4
0x22|SHIFT, // 5
0x23|SHIFT, // 6
0x24|SHIFT, // 7
0x25|SHIFT, // 8
0x26|SHIFT, // 9
0x37, // :
0x36, // ;
0x32, // <
0x2e, // =
0x32|SHIFT, // >
0x10|SHIFT, // ?
0x27|ALT_GR, // @
0x14|SHIFT, // A
0x05|SHIFT, // B
0x06|SHIFT, // C
0x07|SHIFT, // D
0x08|SHIFT, // E
0x09|SHIFT, // F
0x0a|SHIFT, // G
0x0b|SHIFT, // H
0x0c|SHIFT, // I
0x0d|SHIFT, // J
0x0e|SHIFT, // K
0x0f|SHIFT, // L
0x33|SHIFT, // M
0x11|SHIFT, // N
0x12|SHIFT, // O
0x13|SHIFT, // P
0x04|SHIFT, // Q
0x15|SHIFT, // R
0x16|SHIFT, // S
0x17|SHIFT, // T
0x18|SHIFT, // U
0x19|SHIFT, // V
0x1d|SHIFT, // W
0x1b|SHIFT, // X
0x1c|SHIFT, // Y
0x1a|SHIFT, // Z
0x22|ALT_GR, // [
0x25|ALT_GR, // bslash
0x2d|ALT_GR, // ]
0x26|ALT_GR, // ^
0x25, // _
0x24|ALT_GR, // `
0x14, // a
0x05, // b
0x06, // c
0x07, // d
0x08, // e
0x09, // f
0x0a, // g
0x0b, // h
0x0c, // i
0x0d, // j
0x0e, // k
0x0f, // l
0x33, // m
0x11, // n
0x12, // o
0x13, // p
0x04, // q
0x15, // r
0x16, // s
0x17, // t
0x18, // u
0x19, // v
0x1d, // w
0x1b, // x
0x1c, // y
0x1a, // z
0x21|ALT_GR, // {
0x23|ALT_GR, // |
0x2e|ALT_GR, // }
0x1f|ALT_GR, // ~
0x00 // DEL
};
@@ -0,0 +1,144 @@
/*
* Standard HU keyboard layout.
*/
#include "KeyboardLayout.h"
extern const uint8_t KeyboardLayout_hu_HU[128] PROGMEM =
{
0x00, // NUL
0x00, // SOH
0x00, // STX
0x00, // ETX
0x00, // EOT
0x00, // ENQ
0x00, // ACK
0x00, // BEL
0x2a, // BS Backspace
0x2b, // TAB Tab
0x28, // LF Enter
0x00, // VT
0x00, // FF
0x00, // CR
0x00, // SO
0x00, // SI
0x00, // DEL
0x00, // DC1
0x00, // DC2
0x00, // DC3
0x00, // DC4
0x00, // NAK
0x00, // SYN
0x00, // ETB
0x00, // CAN
0x00, // EM
0x00, // SUB
0x00, // ESC
0x00, // FS
0x00, // GS
0x00, // RS
0x00, // US
0x2c, // ' '
0x21|SHIFT, // !
0x1f|SHIFT, // "
0x1b|ALT_GR, // #
0x33|ALT_GR, // $
0x22|SHIFT, // %
0x06|ALT_GR, // &
0x1e|SHIFT, // '
0x25|SHIFT, // (
0x26|SHIFT, // )
0x38|ALT_GR, // *
0x20|SHIFT, // +
0x36, // ,
0x38, // -
0x37, // .
0x23|SHIFT, // /
0x35, // 0
0x1e, // 1
0x1f, // 2
0x20, // 3
0x21, // 4
0x22, // 5
0x23, // 6
0x24, // 7
0x25, // 8
0x26, // 9
0x37|SHIFT, // :
0x36|ALT_GR, // ;
0x32|ALT_GR, // <
0x24|SHIFT, // =
0x1d|ALT_GR, // >
0x36|SHIFT, // ?
0x19|ALT_GR, // @
0x04|SHIFT, // A
0x05|SHIFT, // B
0x06|SHIFT, // C
0x07|SHIFT, // D
0x08|SHIFT, // E
0x09|SHIFT, // F
0x0a|SHIFT, // G
0x0b|SHIFT, // H
0x0c|SHIFT, // I
0x0d|SHIFT, // J
0x0e|SHIFT, // K
0x0f|SHIFT, // L
0x10|SHIFT, // M
0x11|SHIFT, // N
0x12|SHIFT, // O
0x13|SHIFT, // P
0x14|SHIFT, // Q
0x15|SHIFT, // R
0x16|SHIFT, // S
0x17|SHIFT, // T
0x18|SHIFT, // U
0x19|SHIFT, // V
0x1a|SHIFT, // W
0x1b|SHIFT, // X
0x1d|SHIFT, // Y
0x1c|SHIFT, // Z
0x09|ALT_GR, // [
0x14|ALT_GR, // bslash
0x0a|ALT_GR, // ]
0x20|ALT_GR, // ^
0x38|SHIFT, // _
0x24|ALT_GR, // `
0x04, // a
0x05, // b
0x06, // c
0x07, // d
0x08, // e
0x09, // f
0x0a, // g
0x0b, // h
0x0c, // i
0x0d, // j
0x0e, // k
0x0f, // l
0x10, // m
0x11, // n
0x12, // o
0x13, // p
0x14, // q
0x15, // r
0x16, // s
0x17, // t
0x18, // u
0x19, // v
0x1a, // w
0x1b, // x
0x1d, // y
0x1c, // z
0x05|ALT_GR, // {
0x1a|ALT_GR, // |
0x11|ALT_GR, // }
0x1e|ALT_GR, // ~
0x00 // DEL
};
@@ -0,0 +1,138 @@
/*
* Italian keyboard layout.
*/
#include "KeyboardLayout.h"
extern const uint8_t KeyboardLayout_it_IT[128] PROGMEM =
{
0x00, // NUL
0x00, // SOH
0x00, // STX
0x00, // ETX
0x00, // EOT
0x00, // ENQ
0x00, // ACK
0x00, // BEL
0x2a, // BS Backspace
0x2b, // TAB Tab
0x28, // LF Enter
0x00, // VT
0x00, // FF
0x00, // CR
0x00, // SO
0x00, // SI
0x00, // DEL
0x00, // DC1
0x00, // DC2
0x00, // DC3
0x00, // DC4
0x00, // NAK
0x00, // SYN
0x00, // ETB
0x00, // CAN
0x00, // EM
0x00, // SUB
0x00, // ESC
0x00, // FS
0x00, // GS
0x00, // RS
0x00, // US
0x2c, // ' '
0x1e|SHIFT, // !
0x1f|SHIFT, // "
0x34|ALT_GR, // #
0x21|SHIFT, // $
0x22|SHIFT, // %
0x23|SHIFT, // &
0x2d, // '
0x25|SHIFT, // (
0x26|SHIFT, // )
0x30|SHIFT, // *
0x30, // +
0x36, // ,
0x38, // -
0x37, // .
0x24|SHIFT, // /
0x27, // 0
0x1e, // 1
0x1f, // 2
0x20, // 3
0x21, // 4
0x22, // 5
0x23, // 6
0x24, // 7
0x25, // 8
0x26, // 9
0x37|SHIFT, // :
0x36|SHIFT, // ;
0x32, // <
0x27|SHIFT, // =
0x32|SHIFT, // >
0x2d|SHIFT, // ?
0x33|ALT_GR, // @
0x04|SHIFT, // A
0x05|SHIFT, // B
0x06|SHIFT, // C
0x07|SHIFT, // D
0x08|SHIFT, // E
0x09|SHIFT, // F
0x0a|SHIFT, // G
0x0b|SHIFT, // H
0x0c|SHIFT, // I
0x0d|SHIFT, // J
0x0e|SHIFT, // K
0x0f|SHIFT, // L
0x10|SHIFT, // M
0x11|SHIFT, // N
0x12|SHIFT, // O
0x13|SHIFT, // P
0x14|SHIFT, // Q
0x15|SHIFT, // R
0x16|SHIFT, // S
0x17|SHIFT, // T
0x18|SHIFT, // U
0x19|SHIFT, // V
0x1a|SHIFT, // W
0x1b|SHIFT, // X
0x1c|SHIFT, // Y
0x1d|SHIFT, // Z
0x2f|ALT_GR, // [
0x35, // bslash
0x30|ALT_GR, // ]
0x2e|SHIFT, // ^
0x38|SHIFT, // _
0x00, // ` not in this layout
0x04, // a
0x05, // b
0x06, // c
0x07, // d
0x08, // e
0x09, // f
0x0a, // g
0x0b, // h
0x0c, // i
0x0d, // j
0x0e, // k
0x0f, // l
0x10, // m
0x11, // n
0x12, // o
0x13, // p
0x14, // q
0x15, // r
0x16, // s
0x17, // t
0x18, // u
0x19, // v
0x1a, // w
0x1b, // x
0x1c, // y
0x1d, // z
0x00, // { not supported (requires AltGr+Shift)
0x35|SHIFT, // |
0x00, // } not supported (requires AltGr+Shift)
0x00, // ~ not in this layout
0x00 // DEL
};
@@ -0,0 +1,138 @@
/*
* Portuguese keyboard layout.
*/
#include "KeyboardLayout.h"
extern const uint8_t KeyboardLayout_pt_PT[128] PROGMEM =
{
0x00, // NUL
0x00, // SOH
0x00, // STX
0x00, // ETX
0x00, // EOT
0x00, // ENQ
0x00, // ACK
0x00, // BEL
0x2a, // BS Backspace
0x2b, // TAB Tab
0x28, // LF Enter
0x00, // VT
0x00, // FF
0x00, // CR
0x00, // SO
0x00, // SI
0x00, // DEL
0x00, // DC1
0x00, // DC2
0x00, // DC3
0x00, // DC4
0x00, // NAK
0x00, // SYN
0x00, // ETB
0x00, // CAN
0x00, // EM
0x00, // SUB
0x00, // ESC
0x00, // FS
0x00, // GS
0x00, // RS
0x00, // US
0x2c, // ' '
0x1e|SHIFT, // !
0x1f|SHIFT, // "
0x20|SHIFT, // #
0x21|SHIFT, // $
0x22|SHIFT, // %
0x23|SHIFT, // &
0x2d, // '
0x25|SHIFT, // (
0x26|SHIFT, // )
0x2f|SHIFT, // *
0x2f, // +
0x36, // ,
0x38, // -
0x37, // .
0x24|SHIFT, // /
0x27, // 0
0x1e, // 1
0x1f, // 2
0x20, // 3
0x21, // 4
0x22, // 5
0x23, // 6
0x24, // 7
0x25, // 8
0x26, // 9
0x37|SHIFT, // :
0x36|SHIFT, // ;
0x32, // <
0x27|SHIFT, // =
0x32|SHIFT, // >
0x2d|SHIFT, // ?
0x1f|ALT_GR, // @
0x04|SHIFT, // A
0x05|SHIFT, // B
0x06|SHIFT, // C
0x07|SHIFT, // D
0x08|SHIFT, // E
0x09|SHIFT, // F
0x0a|SHIFT, // G
0x0b|SHIFT, // H
0x0c|SHIFT, // I
0x0d|SHIFT, // J
0x0e|SHIFT, // K
0x0f|SHIFT, // L
0x10|SHIFT, // M
0x11|SHIFT, // N
0x12|SHIFT, // O
0x13|SHIFT, // P
0x14|SHIFT, // Q
0x15|SHIFT, // R
0x16|SHIFT, // S
0x17|SHIFT, // T
0x18|SHIFT, // U
0x19|SHIFT, // V
0x1a|SHIFT, // W
0x1b|SHIFT, // X
0x1c|SHIFT, // Y
0x1d|SHIFT, // Z
0x25|ALT_GR, // [
0x35, // bslash
0x26|ALT_GR, // ]
0x00, // ^ not supported (requires dead key + space)
0x38|SHIFT, // _
0x00, // ` not supported (requires dead key + space)
0x04, // a
0x05, // b
0x06, // c
0x07, // d
0x08, // e
0x09, // f
0x0a, // g
0x0b, // h
0x0c, // i
0x0d, // j
0x0e, // k
0x0f, // l
0x10, // m
0x11, // n
0x12, // o
0x13, // p
0x14, // q
0x15, // r
0x16, // s
0x17, // t
0x18, // u
0x19, // v
0x1a, // w
0x1b, // x
0x1c, // y
0x1d, // z
0x24|ALT_GR, // {
0x35|SHIFT, // |
0x27|ALT_GR, // }
0x00, // ~ not supported (requires dead key + space)
0x00 // DEL
};
@@ -0,0 +1,138 @@
/*
* Swedish keyboard layout.
*/
#include "KeyboardLayout.h"
extern const uint8_t KeyboardLayout_sv_SE[128] PROGMEM =
{
0x00, // NUL
0x00, // SOH
0x00, // STX
0x00, // ETX
0x00, // EOT
0x00, // ENQ
0x00, // ACK
0x00, // BEL
0x2a, // BS Backspace
0x2b, // TAB Tab
0x28, // LF Enter
0x00, // VT
0x00, // FF
0x00, // CR
0x00, // SO
0x00, // SI
0x00, // DEL
0x00, // DC1
0x00, // DC2
0x00, // DC3
0x00, // DC4
0x00, // NAK
0x00, // SYN
0x00, // ETB
0x00, // CAN
0x00, // EM
0x00, // SUB
0x00, // ESC
0x00, // FS
0x00, // GS
0x00, // RS
0x00, // US
0x2c, // ' '
0x1e|SHIFT, // !
0x1f|SHIFT, // "
0x20|SHIFT, // #
0x21|ALT_GR, // $
0x22|SHIFT, // %
0x23|SHIFT, // &
0x31, // '
0x25|SHIFT, // (
0x26|SHIFT, // )
0x31|SHIFT, // *
0x2d, // +
0x36, // ,
0x38, // -
0x37, // .
0x24|SHIFT, // /
0x27, // 0
0x1e, // 1
0x1f, // 2
0x20, // 3
0x21, // 4
0x22, // 5
0x23, // 6
0x24, // 7
0x25, // 8
0x26, // 9
0x37|SHIFT, // :
0x36|SHIFT, // ;
0x32, // <
0x27|SHIFT, // =
0x32|SHIFT, // >
0x2d|SHIFT, // ?
0x1f|ALT_GR, // @
0x04|SHIFT, // A
0x05|SHIFT, // B
0x06|SHIFT, // C
0x07|SHIFT, // D
0x08|SHIFT, // E
0x09|SHIFT, // F
0x0a|SHIFT, // G
0x0b|SHIFT, // H
0x0c|SHIFT, // I
0x0d|SHIFT, // J
0x0e|SHIFT, // K
0x0f|SHIFT, // L
0x10|SHIFT, // M
0x11|SHIFT, // N
0x12|SHIFT, // O
0x13|SHIFT, // P
0x14|SHIFT, // Q
0x15|SHIFT, // R
0x16|SHIFT, // S
0x17|SHIFT, // T
0x18|SHIFT, // U
0x19|SHIFT, // V
0x1a|SHIFT, // W
0x1b|SHIFT, // X
0x1c|SHIFT, // Y
0x1d|SHIFT, // Z
0x25|ALT_GR, // [
0x2d|ALT_GR, // bslash
0x26|ALT_GR, // ]
0x00, // ^ not supported (requires dead key + space)
0x38|SHIFT, // _
0x00, // ` not supported (requires dead key + space)
0x04, // a
0x05, // b
0x06, // c
0x07, // d
0x08, // e
0x09, // f
0x0a, // g
0x0b, // h
0x0c, // i
0x0d, // j
0x0e, // k
0x0f, // l
0x10, // m
0x11, // n
0x12, // o
0x13, // p
0x14, // q
0x15, // r
0x16, // s
0x17, // t
0x18, // u
0x19, // v
0x1a, // w
0x1b, // x
0x1c, // y
0x1d, // z
0x24|ALT_GR, // {
0x32|ALT_GR, // |
0x27|ALT_GR, // }
0x00, // ~ not supported (requires dead key + space)
0x00 // DEL
};
@@ -0,0 +1,44 @@
/*
Keyboard_da_DK.h
Copyright (c) 2021, Peter John
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef KEYBOARD_DA_DK_h
#define KEYBOARD_DA_DK_h
#include "HID.h"
#if !defined(_USING_HID)
#warning "Using legacy HID core (non pluggable)"
#else
//================================================================================
//================================================================================
// Keyboard
// DA_DK keys
#define KEY_A_RING (136+0x2f)
#define KEY_SLASHED_O (136+0x34)
#define KEY_ASH (136+0x33)
#define KEY_UMLAUT (136+0x30)
#define KEY_ACUTE_ACC (136+0x2e)
#endif
#endif
@@ -0,0 +1,45 @@
/*
Keyboard_de_DE.h
Copyright (c) 2022, Edgar Bonet
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef KEYBOARD_DE_DE_h
#define KEYBOARD_DE_DE_h
#include "HID.h"
#if !defined(_USING_HID)
#warning "Using legacy HID core (non pluggable)"
#else
//================================================================================
//================================================================================
// Keyboard
// de_DE keys
#define KEY_CIRCUMFLEX (136+0x35)
#define KEY_ESZETT (136+0x2d)
#define KEY_ACUTE (136+0x2e)
#define KEY_U_UMLAUT (136+0x2f)
#define KEY_O_UMLAUT (136+0x33)
#define KEY_A_UMLAUT (136+0x34)
#endif
#endif
@@ -0,0 +1,45 @@
/*
Keyboard_es_ES.h
Copyright (c) 2022, Edgar Bonet
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef KEYBOARD_ES_ES_h
#define KEYBOARD_ES_ES_h
#include "HID.h"
#if !defined(_USING_HID)
#warning "Using legacy HID core (non pluggable)"
#else
//================================================================================
//================================================================================
// Keyboard
// es_ES keys
#define KEY_MASCULINE_ORDINAL (136+0x35)
#define KEY_INVERTED_EXCLAMATION (136+0x2e)
#define KEY_GRAVE (136+0x2f)
#define KEY_N_TILDE (136+0x33)
#define KEY_ACUTE (136+0x34)
#define KEY_C_CEDILLA (136+0x31)
#endif
#endif
@@ -0,0 +1,46 @@
/*
Keyboard_fr_FR.h
Copyright (c) 2022, Edgar Bonet
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef KEYBOARD_FR_FR_h
#define KEYBOARD_FR_FR_h
#include "HID.h"
#if !defined(_USING_HID)
#warning "Using legacy HID core (non pluggable)"
#else
//================================================================================
//================================================================================
// Keyboard
// fr_FR keys
#define KEY_SUPERSCRIPT_TWO (136+0x35)
#define KEY_E_ACUTE (136+0x1f)
#define KEY_E_GRAVE (136+0x24)
#define KEY_C_CEDILLA (136+0x26)
#define KEY_A_GRAVE (136+0x27)
#define KEY_CIRCUMFLEX (136+0x2f)
#define KEY_U_GRAVE (136+0x34)
#endif
#endif
@@ -0,0 +1,52 @@
/*
Keyboard_hu_HU.h
Copyright (c) 2023, Barab(0x34)si Rich(0x34)rd
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef KEYBOARD_HU_HU_h
#define KEYBOARD_HU_HU_h
#include "HID.h"
#if !defined(_USING_HID)
#warning "Using legacy HID core (non pluggable)"
#else
//================================================================================
//================================================================================
// Keyboard
// hu_HU keys
#define KEY_O_ACUTE (136+0x2e)
#define KEY_O_UMLAUT (136+0x27)
#define KEY_O_DOUBLE_ACUTE (136+0x2f)
#define KEY_U_ACUTE (136+0x30)
#define KEY_U_UMLAUT (136+0x2d)
#define KEY_U_DOUBLE_ACUTE (136+0x31)
#define KEY_A_ACUTE (136+0x34)
#define KEY_E_ACUTE (136+0x33)
#define KEY_I_ACUTE (136+0x32)
#endif
#endif
@@ -0,0 +1,44 @@
/*
Keyboard_it_IT.h
Copyright (c) 2022, Edgar Bonet
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef KEYBOARD_IT_IT_h
#define KEYBOARD_IT_IT_h
#include "HID.h"
#if !defined(_USING_HID)
#warning "Using legacy HID core (non pluggable)"
#else
//================================================================================
//================================================================================
// Keyboard
// it_IT keys
#define KEY_I_GRAVE (136+0x2e)
#define KEY_E_GRAVE (136+0x2f)
#define KEY_O_GRAVE (136+0x33)
#define KEY_A_GRAVE (136+0x34)
#define KEY_U_GRAVE (136+0x31)
#endif
#endif
@@ -0,0 +1,44 @@
/*
Keyboard_pt_PT.h
Copyright (c) 2022, Edgar Bonet
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef KEYBOARD_PT_PT_h
#define KEYBOARD_PT_PT_h
#include "HID.h"
#if !defined(_USING_HID)
#warning "Using legacy HID core (non pluggable)"
#else
//================================================================================
//================================================================================
// Keyboard
// pt_PT keys
#define KEY_LEFT_GUILLEMET (136+0x2e)
#define KEY_ACUTE (136+0x30)
#define KEY_C_CEDILLA (136+0x33)
#define KEY_MASCULINE_ORDINAL (136+0x34)
#define KEY_TILDE (136+0x31)
#endif
#endif
@@ -0,0 +1,44 @@
/*
Keyboard_sv_SE.h
Copyright (c) 2021, Peter John
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef KEYBOARD_SV_SE_h
#define KEYBOARD_SV_SE_h
#include "HID.h"
#if !defined(_USING_HID)
#warning "Using legacy HID core (non pluggable)"
#else
//================================================================================
//================================================================================
// Keyboard
// SV_SE keys
#define KEY_A_RING (136+0x2f)
#define KEY_A_UMLAUT (136+0x34)
#define KEY_O_UMLAUT (136+0x33)
#define KEY_UMLAUT (136+0x30)
#define KEY_ACUTE_ACC (136+0x2e)
#endif
#endif
@@ -0,0 +1,315 @@
// Based on the work by DFRobot
#include "LiquidCrystal_I2C.h"
#include <inttypes.h>
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#define printIIC(args) Wire.write(args)
inline size_t LiquidCrystal_I2C::write(uint8_t value) {
send(value, Rs);
return 1;
}
#else
#include "WProgram.h"
#define printIIC(args) Wire.send(args)
inline void LiquidCrystal_I2C::write(uint8_t value) {
send(value, Rs);
}
#endif
#include "Wire.h"
// When the display powers up, it is configured as follows:
//
// 1. Display clear
// 2. Function set:
// DL = 1; 8-bit interface data
// N = 0; 1-line display
// F = 0; 5x8 dot character font
// 3. Display on/off control:
// D = 0; Display off
// C = 0; Cursor off
// B = 0; Blinking off
// 4. Entry mode set:
// I/D = 1; Increment by 1
// S = 0; No shift
//
// Note, however, that resetting the Arduino doesn't reset the LCD, so we
// can't assume that its in that state when a sketch starts (and the
// LiquidCrystal constructor is called).
LiquidCrystal_I2C::LiquidCrystal_I2C(uint8_t lcd_Addr,uint8_t lcd_cols,uint8_t lcd_rows)
{
_Addr = lcd_Addr;
_cols = lcd_cols;
_rows = lcd_rows;
_backlightval = LCD_NOBACKLIGHT;
}
void LiquidCrystal_I2C::init(){
init_priv();
}
void LiquidCrystal_I2C::init_priv()
{
Wire.begin();
_displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS;
begin(_cols, _rows);
}
void LiquidCrystal_I2C::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) {
if (lines > 1) {
_displayfunction |= LCD_2LINE;
}
_numlines = lines;
// for some 1 line displays you can select a 10 pixel high font
if ((dotsize != 0) && (lines == 1)) {
_displayfunction |= LCD_5x10DOTS;
}
// SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!
// according to datasheet, we need at least 40ms after power rises above 2.7V
// before sending commands. Arduino can turn on way befer 4.5V so we'll wait 50
delay(50);
// Now we pull both RS and R/W low to begin commands
expanderWrite(_backlightval); // reset expanderand turn backlight off (Bit 8 =1)
delay(1000);
//put the LCD into 4 bit mode
// this is according to the hitachi HD44780 datasheet
// figure 24, pg 46
// we start in 8bit mode, try to set 4 bit mode
write4bits(0x03 << 4);
delayMicroseconds(4500); // wait min 4.1ms
// second try
write4bits(0x03 << 4);
delayMicroseconds(4500); // wait min 4.1ms
// third go!
write4bits(0x03 << 4);
delayMicroseconds(150);
// finally, set to 4-bit interface
write4bits(0x02 << 4);
// set # lines, font size, etc.
command(LCD_FUNCTIONSET | _displayfunction);
// turn the display on with no cursor or blinking default
_displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;
display();
// clear it off
clear();
// Initialize to default text direction (for roman languages)
_displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
// set the entry mode
command(LCD_ENTRYMODESET | _displaymode);
home();
}
/********** high level commands, for the user! */
void LiquidCrystal_I2C::clear(){
command(LCD_CLEARDISPLAY);// clear display, set cursor position to zero
delayMicroseconds(2000); // this command takes a long time!
}
void LiquidCrystal_I2C::home(){
command(LCD_RETURNHOME); // set cursor position to zero
delayMicroseconds(2000); // this command takes a long time!
}
void LiquidCrystal_I2C::setCursor(uint8_t col, uint8_t row){
int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };
if ( row > _numlines ) {
row = _numlines-1; // we count rows starting w/0
}
command(LCD_SETDDRAMADDR | (col + row_offsets[row]));
}
// Turn the display on/off (quickly)
void LiquidCrystal_I2C::noDisplay() {
_displaycontrol &= ~LCD_DISPLAYON;
command(LCD_DISPLAYCONTROL | _displaycontrol);
}
void LiquidCrystal_I2C::display() {
_displaycontrol |= LCD_DISPLAYON;
command(LCD_DISPLAYCONTROL | _displaycontrol);
}
// Turns the underline cursor on/off
void LiquidCrystal_I2C::noCursor() {
_displaycontrol &= ~LCD_CURSORON;
command(LCD_DISPLAYCONTROL | _displaycontrol);
}
void LiquidCrystal_I2C::cursor() {
_displaycontrol |= LCD_CURSORON;
command(LCD_DISPLAYCONTROL | _displaycontrol);
}
// Turn on and off the blinking cursor
void LiquidCrystal_I2C::noBlink() {
_displaycontrol &= ~LCD_BLINKON;
command(LCD_DISPLAYCONTROL | _displaycontrol);
}
void LiquidCrystal_I2C::blink() {
_displaycontrol |= LCD_BLINKON;
command(LCD_DISPLAYCONTROL | _displaycontrol);
}
// These commands scroll the display without changing the RAM
void LiquidCrystal_I2C::scrollDisplayLeft(void) {
command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT);
}
void LiquidCrystal_I2C::scrollDisplayRight(void) {
command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT);
}
// This is for text that flows Left to Right
void LiquidCrystal_I2C::leftToRight(void) {
_displaymode |= LCD_ENTRYLEFT;
command(LCD_ENTRYMODESET | _displaymode);
}
// This is for text that flows Right to Left
void LiquidCrystal_I2C::rightToLeft(void) {
_displaymode &= ~LCD_ENTRYLEFT;
command(LCD_ENTRYMODESET | _displaymode);
}
// This will 'right justify' text from the cursor
void LiquidCrystal_I2C::autoscroll(void) {
_displaymode |= LCD_ENTRYSHIFTINCREMENT;
command(LCD_ENTRYMODESET | _displaymode);
}
// This will 'left justify' text from the cursor
void LiquidCrystal_I2C::noAutoscroll(void) {
_displaymode &= ~LCD_ENTRYSHIFTINCREMENT;
command(LCD_ENTRYMODESET | _displaymode);
}
// Allows us to fill the first 8 CGRAM locations
// with custom characters
void LiquidCrystal_I2C::createChar(uint8_t location, uint8_t charmap[]) {
location &= 0x7; // we only have 8 locations 0-7
command(LCD_SETCGRAMADDR | (location << 3));
for (int i=0; i<8; i++) {
write(charmap[i]);
}
}
// Turn the (optional) backlight off/on
void LiquidCrystal_I2C::noBacklight(void) {
_backlightval=LCD_NOBACKLIGHT;
expanderWrite(0);
}
void LiquidCrystal_I2C::backlight(void) {
_backlightval=LCD_BACKLIGHT;
expanderWrite(0);
}
/*********** mid level commands, for sending data/cmds */
inline void LiquidCrystal_I2C::command(uint8_t value) {
send(value, 0);
}
/************ low level data pushing commands **********/
// write either command or data
void LiquidCrystal_I2C::send(uint8_t value, uint8_t mode) {
uint8_t highnib=value&0xf0;
uint8_t lownib=(value<<4)&0xf0;
write4bits((highnib)|mode);
write4bits((lownib)|mode);
}
void LiquidCrystal_I2C::write4bits(uint8_t value) {
expanderWrite(value);
pulseEnable(value);
}
void LiquidCrystal_I2C::expanderWrite(uint8_t _data){
Wire.beginTransmission(_Addr);
printIIC((int)(_data) | _backlightval);
Wire.endTransmission();
}
void LiquidCrystal_I2C::pulseEnable(uint8_t _data){
expanderWrite(_data | En); // En high
delayMicroseconds(1); // enable pulse must be >450ns
expanderWrite(_data & ~En); // En low
delayMicroseconds(50); // commands need > 37us to settle
}
// Alias functions
void LiquidCrystal_I2C::cursor_on(){
cursor();
}
void LiquidCrystal_I2C::cursor_off(){
noCursor();
}
void LiquidCrystal_I2C::blink_on(){
blink();
}
void LiquidCrystal_I2C::blink_off(){
noBlink();
}
void LiquidCrystal_I2C::load_custom_character(uint8_t char_num, uint8_t *rows){
createChar(char_num, rows);
}
void LiquidCrystal_I2C::setBacklight(uint8_t new_val){
if(new_val){
backlight(); // turn backlight on
}else{
noBacklight(); // turn backlight off
}
}
void LiquidCrystal_I2C::printstr(const char c[]){
//This function is not identical to the function used for "real" I2C displays
//it's here so the user sketch doesn't have to be changed
print(c);
}
// unsupported API functions
void LiquidCrystal_I2C::off(){}
void LiquidCrystal_I2C::on(){}
void LiquidCrystal_I2C::setDelay (int cmdDelay,int charDelay) {}
uint8_t LiquidCrystal_I2C::status(){return 0;}
uint8_t LiquidCrystal_I2C::keypad (){return 0;}
uint8_t LiquidCrystal_I2C::init_bargraph(uint8_t graphtype){return 0;}
void LiquidCrystal_I2C::draw_horizontal_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_col_end){}
void LiquidCrystal_I2C::draw_vertical_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_row_end){}
void LiquidCrystal_I2C::setContrast(uint8_t new_val){}
@@ -0,0 +1,126 @@
//YWROBOT
#ifndef LiquidCrystal_I2C_h
#define LiquidCrystal_I2C_h
#include <inttypes.h>
#include "Print.h"
#include <Wire.h>
// commands
#define LCD_CLEARDISPLAY 0x01
#define LCD_RETURNHOME 0x02
#define LCD_ENTRYMODESET 0x04
#define LCD_DISPLAYCONTROL 0x08
#define LCD_CURSORSHIFT 0x10
#define LCD_FUNCTIONSET 0x20
#define LCD_SETCGRAMADDR 0x40
#define LCD_SETDDRAMADDR 0x80
// flags for display entry mode
#define LCD_ENTRYRIGHT 0x00
#define LCD_ENTRYLEFT 0x02
#define LCD_ENTRYSHIFTINCREMENT 0x01
#define LCD_ENTRYSHIFTDECREMENT 0x00
// flags for display on/off control
#define LCD_DISPLAYON 0x04
#define LCD_DISPLAYOFF 0x00
#define LCD_CURSORON 0x02
#define LCD_CURSOROFF 0x00
#define LCD_BLINKON 0x01
#define LCD_BLINKOFF 0x00
// flags for display/cursor shift
#define LCD_DISPLAYMOVE 0x08
#define LCD_CURSORMOVE 0x00
#define LCD_MOVERIGHT 0x04
#define LCD_MOVELEFT 0x00
// flags for function set
#define LCD_8BITMODE 0x10
#define LCD_4BITMODE 0x00
#define LCD_2LINE 0x08
#define LCD_1LINE 0x00
#define LCD_5x10DOTS 0x04
#define LCD_5x8DOTS 0x00
// flags for backlight control
#define LCD_BACKLIGHT 0x08
#define LCD_NOBACKLIGHT 0x00
#define En B00000100 // Enable bit
#define Rw B00000010 // Read/Write bit
#define Rs B00000001 // Register select bit
class LiquidCrystal_I2C : public Print {
public:
LiquidCrystal_I2C(uint8_t lcd_Addr,uint8_t lcd_cols,uint8_t lcd_rows);
void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS );
void clear();
void home();
void noDisplay();
void display();
void noBlink();
void blink();
void noCursor();
void cursor();
void scrollDisplayLeft();
void scrollDisplayRight();
void printLeft();
void printRight();
void leftToRight();
void rightToLeft();
void shiftIncrement();
void shiftDecrement();
void noBacklight();
void backlight();
void autoscroll();
void noAutoscroll();
void createChar(uint8_t, uint8_t[]);
void setCursor(uint8_t, uint8_t);
#if defined(ARDUINO) && ARDUINO >= 100
virtual size_t write(uint8_t);
#else
virtual void write(uint8_t);
#endif
void command(uint8_t);
void init();
////compatibility API function aliases
void blink_on(); // alias for blink()
void blink_off(); // alias for noBlink()
void cursor_on(); // alias for cursor()
void cursor_off(); // alias for noCursor()
void setBacklight(uint8_t new_val); // alias for backlight() and nobacklight()
void load_custom_character(uint8_t char_num, uint8_t *rows); // alias for createChar()
void printstr(const char[]);
////Unsupported API functions (not implemented in this library)
uint8_t status();
void setContrast(uint8_t new_val);
uint8_t keypad();
void setDelay(int,int);
void on();
void off();
uint8_t init_bargraph(uint8_t graphtype);
void draw_horizontal_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_col_end);
void draw_vertical_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_col_end);
private:
void init_priv();
void send(uint8_t, uint8_t);
void write4bits(uint8_t);
void expanderWrite(uint8_t);
void pulseEnable(uint8_t);
uint8_t _Addr;
uint8_t _displayfunction;
uint8_t _displaycontrol;
uint8_t _displaymode;
uint8_t _numlines;
uint8_t _cols;
uint8_t _rows;
uint8_t _backlightval;
};
#endif
+123
View File
@@ -0,0 +1,123 @@
/*
Mouse.cpp
Copyright (c) 2015, Arduino LLC
Original code (pre-library): Copyright (c) 2011, Peter Barrett
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "Mouse.h"
#if defined(_USING_HID)
static const uint8_t _hidReportDescriptor[] PROGMEM = {
// Mouse
0x05, 0x01, // USAGE_PAGE (Generic Desktop) // 54
0x09, 0x02, // USAGE (Mouse)
0xa1, 0x01, // COLLECTION (Application)
0x09, 0x01, // USAGE (Pointer)
0xa1, 0x00, // COLLECTION (Physical)
0x85, 0x01, // REPORT_ID (1)
0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x01, // USAGE_MINIMUM (Button 1)
0x29, 0x03, // USAGE_MAXIMUM (Button 3)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x95, 0x03, // REPORT_COUNT (3)
0x75, 0x01, // REPORT_SIZE (1)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x05, // REPORT_SIZE (5)
0x81, 0x03, // INPUT (Cnst,Var,Abs)
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x30, // USAGE (X)
0x09, 0x31, // USAGE (Y)
0x09, 0x38, // USAGE (Wheel)
0x15, 0x81, // LOGICAL_MINIMUM (-127)
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x03, // REPORT_COUNT (3)
0x81, 0x06, // INPUT (Data,Var,Rel)
0xc0, // END_COLLECTION
0xc0, // END_COLLECTION
};
//================================================================================
//================================================================================
// Mouse
Mouse_::Mouse_(void) : _buttons(0)
{
static HIDSubDescriptor node(_hidReportDescriptor, sizeof(_hidReportDescriptor));
HID().AppendDescriptor(&node);
}
void Mouse_::begin(void)
{
}
void Mouse_::end(void)
{
}
void Mouse_::click(uint8_t b)
{
_buttons = b;
move(0,0,0);
_buttons = 0;
move(0,0,0);
}
void Mouse_::move(signed char x, signed char y, signed char wheel)
{
uint8_t m[4];
m[0] = _buttons;
m[1] = x;
m[2] = y;
m[3] = wheel;
HID().SendReport(1,m,4);
}
void Mouse_::buttons(uint8_t b)
{
if (b != _buttons)
{
_buttons = b;
move(0,0,0);
}
}
void Mouse_::press(uint8_t b)
{
buttons(_buttons | b);
}
void Mouse_::release(uint8_t b)
{
buttons(_buttons & ~b);
}
bool Mouse_::isPressed(uint8_t b)
{
if ((b & _buttons) > 0)
return true;
return false;
}
Mouse_ Mouse;
#endif
+60
View File
@@ -0,0 +1,60 @@
/*
Mouse.h
Copyright (c) 2015, Arduino LLC
Original code (pre-library): Copyright (c) 2011, Peter Barrett
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef MOUSE_h
#define MOUSE_h
#include "HID.h"
#if !defined(_USING_HID)
#warning "Using legacy HID core (non pluggable)"
#else
//================================================================================
//================================================================================
// Mouse
#define MOUSE_LEFT 1
#define MOUSE_RIGHT 2
#define MOUSE_MIDDLE 4
#define MOUSE_ALL (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)
class Mouse_
{
private:
uint8_t _buttons;
void buttons(uint8_t b);
public:
Mouse_(void);
void begin(void);
void end(void);
void click(uint8_t b = MOUSE_LEFT);
void move(signed char x, signed char y, signed char wheel = 0);
void press(uint8_t b = MOUSE_LEFT); // press LEFT by default
void release(uint8_t b = MOUSE_LEFT); // release LEFT by default
bool isPressed(uint8_t b = MOUSE_LEFT); // check LEFT by default
};
extern Mouse_ Mouse;
#endif
#endif
+196
View File
@@ -0,0 +1,196 @@
#include <GyverOLED.h>
#include <GyverEncoder.h>
#include <Wire.h>
#include <EEPROM.h>
#include <Keyboard.h>
#include <Mouse.h>
#include <LiquidCrystal_I2C.h>
// === НАСТРОЙКА ДЕБАГА ===
#define DEBUG_MODE 1 // Поставь 0 (или закомментируй), чтобы ПОЛНОСТЬЮ отключить дебаг
#if (DEBUG_MODE == 1)
// Если дебаг включен, макрос DEB_PRINT превращается в обычный Serial.println
#define DEB_PRINT(x) Serial.println(x)
#define DEB_INIT() \
Serial.begin(9600); \
while (!Serial && (millis() < 2000)); \
Serial.println(F("=== ДЕБАГ АКТИВЕН ==="))
#else
// Если дебаг выключен, макросы превращаются в ПУСТОТУ.
#define DEB_PRINT(x)
#define DEB_INIT()
#endif
#define PRIMARY_EEPROM_WRITE_MODE 0 // Поставь 0 (или закомментируй), чтобы ПОЛНОСТЬЮ отключить дебаг
#if (PRIMARY_EEPROM_WRITE_MODE == 1)
// Если дебаг включен, макрос WRITE_TEST_PASSES() превращается в обычный Serial.println
#define WRITE_TEST_PASSES() fillEEPROMWithData()
#else
// Если дебаг выключен, макросы превращаются в ПУСТОТУ.
#define WRITE_TEST_PASSES()
#endif
// ========================
void updateDisplay();
void fillEEPROMWithData();
String readPassword(int idx);
const int SLOT_SIZE = 50;
GyverOLED<SSD1306_128x32, OLED_BUFFER> oled;
Encoder enc(9, 8, 7);
LiquidCrystal_I2C lcd(0x27,16,2); // Задаем адрес и размер дисплея
int counter = 1;
enum DeviceMode { MODE_INFO, MODE_WRITE, MODE_GAMEPAD };
DeviceMode currentMode = MODE_INFO;
int currentSlot = 0;
// Классический стабильный массив строк скрипта во Flash-памяти
const char pythonScript[] PROGMEM =
"import serial, sys, time\n"
"import serial.tools.list_ports\n"
"print('--- MACROPAD 20-SLOT CONFIGURATOR ---')\n"
"ports = list(serial.tools.list_ports.comports())\n"
"if not ports:\n"
" print('No COM ports found!'); sys.exit()\n"
"print('Available ports:')\n"
"for i, p in enumerate(ports): print(f'{i}: {p.device}')\n"
"idx = int(input('Select port index: '))\n"
"port = ports[idx].device\n"
"try:\n"
" ser = serial.Serial(port, 115200, timeout=1)\n"
" time.sleep(2)\n"
" slot = int(input('Enter slot number (1-20): '))\n"
" password = input('Enter new password: ')\n"
" cmd = f'SET:{slot-1}:{password}\\n'\n"
" ser.write(cmd.encode('utf-8'))\n"
" print('Password successfully saved to Macropad!')\n"
" ser.close()\n"
"except Exception as e:\n"
" print(f'Error: {e}')\n"
"input('\\nPress Enter to exit...')\n";
void setup() {
DEB_INIT(); // Инициализация порта (испарится, если DEBUG_MODE = 0)
DEB_PRINT(F("Старт дисплея..."));
oled.init();
oled.clear();
WRITE_TEST_PASSES();
enc.setType(TYPE2);
updateDisplay();
lcd.init(); // Инициализация lcd
lcd.backlight(); // Включаем подсветку
lcd.setCursor(0,0); // Устанавливаем курсор в начало 1 строки
lcd.print("Hello, world"); // Выводим текст
lcd.setCursor(0,1); // Устанавливаем курсор в начало 2 строки
lcd.print("www.robotchip.ru"); // Выводим текст
}
void loop() {
enc.tick();
if (enc.isTurn()) {
DEB_PRINT(F("Поворот энкодера!"));
if (enc.isRight() && counter < 20) counter++;
if (enc.isLeft() && counter > 1) counter--;
updateDisplay();
}
if (enc.isClick()) {
DEB_PRINT(F("Клик!"));
counter = 1;
updateDisplay();
}
}
void updateDisplaySinus() {
DEB_PRINT(F("Отрисовка синусоиды..."));
oled.clear(); // Очищаем буфер
// Если счетчик равен 0, деление сломает логику, приравняем к 1
int frequency = counter;
//if (frequency == 0) frequency = 1;
// Цикл идет по всей ширине экрана (128 пикселей)
for (int x = 0; x < 128; x++) {
// Вычисляем Y по формуле:
// 16 — это центр экрана 128x32 по вертикали
// 12 — амплитуда (волна будет колебаться от 4 до 28 пикселя)
// frequency — управляет тем, сколько волн поместится на экране
float angle = (float)x / 10.0 * ((float)frequency / 1.0);
int y = 16 + 12 * sin(angle);
// Проверяем, чтобы Y случайно не вышел за границы экрана (0..31)
if (y >= 0 && y < 32) {
oled.dot(x, y); // Рисуем точку синусоиды
}
}
// Для наглядности выведем значение счетчика в углу мелким шрифтом
// oled.setScale(1);
// oled.setCursor(2, 0);
// oled.print(F("F: "));
// oled.print(counter);
oled.update(); // Выводим буфер на экран
DEB_PRINT(F(" [ОК] Синусоида выведена"));
}
void updateDisplay() {
DEB_PRINT(F("Обновление экрана..."));
oled.clear();
oled.setScale(0);
oled.setCursor(0, 0);
oled.print("Slot :");
oled.print(counter);
oled.setCursor(0, 1);
oled.print(readPassword(counter));
DEB_PRINT(("Читаем пароль номер"+ String(counter)+ " " + readPassword(counter)));
oled.update();
}
void fillEEPROMWithData() {
DEB_PRINT(F("Начало записи памяти"));
String hotkeys[4] = {"SuperSecret123!", "WorkPass2026#", "QwErTy_9876", "My_Mega_Password"};
for (int slot = 0; slot < 4; slot++) {
int addr = slot * SLOT_SIZE; String pass = hotkeys[slot];
for (unsigned int i = 0; i < SLOT_SIZE - 1; i++) { EEPROM.update(addr + i, (i < pass.length()) ? pass[i] : '\0'); }
EEPROM.update(addr + SLOT_SIZE - 1, '\0');
DEB_PRINT(("Записан пароль" + String(slot)+ " " + pass));
}
for (int slot = 4; slot < 20; slot++) {
int addr = slot * SLOT_SIZE; String pass = "ArchPass_" + String(slot + 1);
for (unsigned int i = 0; i < SLOT_SIZE - 1; i++) { EEPROM.update(addr + i, (i < pass.length()) ? pass[i] : '\0'); }
EEPROM.update(addr + SLOT_SIZE - 1, '\0');
DEB_PRINT(("Записан пароль" + String(slot)+ " " + pass));
}
}
String readPassword(int idx) {
String p = "";
for (int i = 0; i < SLOT_SIZE; i++) {
char c = EEPROM.read(idx * SLOT_SIZE + i);
if (c == '\0' || c == 255) break;
p += c;
}
return p;
}
+268
View File
@@ -0,0 +1,268 @@
#define EB_DEB_TIME 30
#include <GyverOLED.h>
#include <Wire.h>
#include <EEPROM.h>
#include <Keyboard.h>
#include <Mouse.h>
#include <EncButton.h> // Используем одну библиотеку для всего
// === НАСТРОЙКА ДЕБАГА ===
#define DEBUG_MODE 1 // Поставь 0 (или закомментируй), чтобы ПОЛНОСТЬЮ отключить дебаг
#if (DEBUG_MODE == 1)
// Если дебаг включен, макрос DEB_PRINT превращается в обычный Serial.println
#define DEB_PRINT(x) Serial.println(x)
#define DEB_INIT() \
Serial.begin(9600); \
while (!Serial && (millis() < 2000)); \
Serial.println(F("=== ДЕБАГ АКТИВЕН ==="))
#else
// Если дебаг выключен, макросы превращаются в ПУСТОТУ.
#define DEB_PRINT(x)
#define DEB_INIT()
#endif
#define PRIMARY_EEPROM_WRITE_MODE 1 // Поставь 0 (или закомментируй), чтобы отключить запись тестовых паролей в память
#if (PRIMARY_EEPROM_WRITE_MODE == 1)
// Если дебаг включен, макрос WRITE_TEST_PASSES() превращается в обычный fillEEPROMWithData()
#define WRITE_TEST_PASSES() fillEEPROMWithData()
#else
// Если дебаг выключен, макросы превращаются в ПУСТОТУ.
#define WRITE_TEST_PASSES()
#endif
// ========================
static constexpr uint8_t ENCODER_CLK = 15;
static constexpr uint8_t ENCODER_DT = 14;
static constexpr uint8_t ENCODER_SW = 16;
static constexpr uint8_t MODE_BUTTON_PIN = 6; // Пин для кнопки изменения режима
void updateDisplay();
void updateDisplaySinus();
void fillEEPROMWithData();
void printPythonScript();
void printPass(int idx);
String readPassword(int idx);
const int SLOT_SIZE = 50;
const int HALF_SLOT_SIZE = 25;
// Твой рабочий OLED 128x64 с буфером
GyverOLED<SSD1306_128x64, OLED_BUFFER> oled;
// Инициализируем энкодер с кнопкой через EncButton. Порядок пинов: CLK, DT, SW
EncButton enc(ENCODER_CLK, ENCODER_DT, ENCODER_SW);
EncButton modeButton(MODE_BUTTON_PIN); // Создаем объект для отдельной кнопки
int counter = 1;
enum DeviceMode { MODE_INFO, MODE_WRITE, MODE_GAMEPAD };
DeviceMode currentMode = MODE_INFO;
bool showPasswords = true; // Новый флаг для отображения паролей
// Классический стабильный массив строк скрипта во Flash-памяти
const char pythonScript[] PROGMEM =
"import serial, sys, time\n"
"import serial.tools.list_ports\n"
"print('--- MACROPAD 20-SLOT CONFIGURATOR ---')\n"
"ports = list(serial.tools.list_ports.comports())\n"
"if not ports:\n"
" print('No COM ports found!'); sys.exit()\n"
"print('Available ports:')\n"
"for i, p in enumerate(ports): print(f'{i}: {p.device}')\n"
"idx = int(input('Select port index: '))\n"
"port = ports[idx].device\n"
"try:\n"
" ser = serial.Serial(port, 115200, timeout=1)\n"
" time.sleep(2)\n"
" slot = int(input('Enter slot number (1-20): '))\n"
" password = input('Enter new password: ')\n"
" cmd = f'SET:{slot-1}:{password}\\n'\n"
" ser.write(cmd.encode('utf-8'))\n"
" print('Password successfully saved to Macropad!')\n"
" ser.close()\n"
"except Exception as e:\n"
" print(f'Error: {e}')\n"
"input('\\nPress Enter to exit...')\n";
void setup() {
DEB_INIT(); // Инициализация порта (испарится, если DEBUG_MODE = 0)
DEB_PRINT(F("Старт дисплея..."));
oled.init();
oled.clear();
Keyboard.begin(); // Инициализация клавиатуры
WRITE_TEST_PASSES();
// enc.setType(TYPE2); // Больше не нужно, EncButton сама отлично обрабатывает типы энкодеров
// Вместо старого lcd.init() выводим приветствие на OLED
oled.setScale(1); // Мелкий шрифт, чтобы всё влезло на 128x64
oled.setCursor(0, 0); // 1 строка
oled.print("Hello, world");
oled.setCursor(0, 2); // 2 строка (у 128x64 шаг строки равен 2)
oled.print("www.robotchip.ru");
oled.update(); // Выталкиваем буфер приветствия на экран
delay(2000); // Даем пару секунд рассмотреть заставку, как на старом LCD
updateDisplay(); // Переходим к рабочему экрану со слотами
}
void loop() {
// Опрашиваем устройства
enc.tick();
modeButton.tick();
// Проверка поворота энкодера
if (enc.isTurn()) {
DEB_PRINT(F("Поворот энкодера!"));
if (enc.isRight() && counter < 20) counter++;
if (enc.isLeft() && counter > 1) counter--;
updateDisplay();
}
// Проверка клика по встроенной кнопке энкодера
if (enc.isClick()) {
DEB_PRINT(F("Клик!"));
printPass(counter-1);
updateDisplay();
}
// Обработка нажатия отдельной кнопки для изменения режима
if (modeButton.isClick()) { // Изменено с .click() на .isClick() для единообразия EncButton
DEB_PRINT(F("Кнопка режима была нажата!"));
currentMode = static_cast<DeviceMode>((currentMode + 1) % 3); // Переключаем режимы: MODE_INFO, MODE_WRITE, MODE_GAMEPAD
updateDisplay(); // Обновляем экран
}
}
void updateDisplaySinus() {
DEB_PRINT(F("Отрисовка синусоиды..."));
oled.clear(); // Очищаем буфер
int frequency = counter;
// Цикл идет по всей ширине экрана (128 пикселей)
for (int x = 0; x < 128; x++) {
// 32 — это центр экрана 128x64 по вертикали
// 20 — амплитуда
float angle = (float)x / 10.0 * ((float)frequency / 1.0);
int y = 32 + 20 * sin(angle);
if (y >= 0 && y < 64) {
oled.dot(x, y); // Рисуем точку синусоиды
}
}
oled.update(); // Выводим буфер на экран
DEB_PRINT(F(" [ОК] Синусоида выведена"));
}
void updateDisplay() {
DEB_PRINT(F("Обновление экрана..."));
oled.clear();
oled.setScale(2); // Используем масштаб 2, как было в твоем коде (в комментарии опечатка про 1)
oled.setCursor(0, 0);
oled.print("Slot :");
oled.print(counter);
switch (currentMode) {
case MODE_INFO:
oled.setCursor(0, 2);
if (showPasswords) {
oled.print(readPassword(counter-1));
} else {
oled.print("******");
}
break;
case MODE_WRITE:
oled.setCursor(0, 2);
oled.print("Mode: WRITE");
break;
case MODE_GAMEPAD:
updateDisplaySinus();
return; // Возвращаемся из функции, так как синусоида уже отрисована
break;
}
DEB_PRINT(("Читаем пароль номер"+ String(counter)+ " " + readPassword(counter)));
oled.update();
}
void fillEEPROMWithData() {
DEB_PRINT(F("Начало записи памяти"));
String hotkeys[4][2] = {{"Main password", "SuperSecret123!"}, {"Second password", "WorkPass2026#" }, {"Third password", "P@ssw0rd!"},{"Fourth password", "My_Mega_Password"}};
for (int slot = 0; slot < 4; slot++) {
int addr = slot * SLOT_SIZE; String name = hotkeys[slot][0]; String pass = hotkeys[slot][1];
for (unsigned int i = 0; i < SLOT_SIZE - 1; i++) {
EEPROM.update(addr + i, (i < pass.length()) ? pass[i] : '\0');
}
EEPROM.update(addr + SLOT_SIZE - 1, '\0');
DEB_PRINT(("Записан пароль" + String(slot)+ " " + pass));
}
for (int slot = 4; slot < 20; slot++) {
int addr = slot * SLOT_SIZE; String pass = "ANGELINA YA TEBYA LUBLU"
//+ String(slot + 1)
;
for (unsigned int i = 0; i < SLOT_SIZE - 1; i++) {
EEPROM.update(addr + i, (i < pass.length()) ? pass[i] : '\0');
}
EEPROM.update(addr + SLOT_SIZE - 1, '\0');
DEB_PRINT(("Записан пароль" + String(slot)+ " " + pass));
}
}
String readPassword(int idx) {
String p = "";
for (int i = 0; i < SLOT_SIZE; i++) {
char c = EEPROM.read(idx * SLOT_SIZE + i);
if (c == '\0' || c == 255) break;
p += c;
}
return p;
}
void printPass(int idx) {
DEB_PRINT(F("Начинаем выплескивать пароль..."));
String pass = readPassword(idx);
Keyboard.print(pass);
DEB_PRINT(F("Пароль выплеснут!"));
}
void printPythonScript() {
DEB_PRINT(F("Начинаем выплескивать Python-скрипт..."));
int i = 0;
while (true) {
// Читаем один символ прямо из Flash-памяти
char c = pgm_read_byte(&(pythonScript[i]));
// Если дошли до конца строки (нулевой байт в Си-строках) — выходим
if (c == '\0') break;
// Печатаем символ в ПК, как будто жмем кнопку на клавиатуре
Keyboard.write(c);
i++;
// Маленькая задержка между символами.
// Если ПК «захлебывается» и пропускает буквы, подними до 2-5 мс
delay(3);
}
DEB_PRINT(F("Скрипт полностью напечатан!"));
}
Binary file not shown.
+278
View File
@@ -0,0 +1,278 @@
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
#include <Keyboard.h>
#include <Mouse.h>
#include <avr/pgmspace.h>
// 1. ОБЪЯВЛЯЕМ ПРОТОТИПЫ ФУНКЦИЙ ДЛЯ КОМПИЛЯТОРА
void updateDisplay();
void fillEEPROMWithData();
void handleGamepadMode();
void handlePasswordModes();
void checkIncomingSerial();
void checkModeButton();
void sendPassword(int idx);
String readPassword(int idx);
// Инициализация дисплея
LiquidCrystal_I2C lcd(0x27, 16, 2);
const int SLOT_SIZE = 50;
// ПИНЫ
const int JOY_Y_PIN = A1;
const int JOY_X_PIN = A2;
const int JOY_SW_PIN = 9;
const int BTN_A = 4;
const int BTN_B = 5;
const int BTN_X = 6;
const int BTN_Y = 7;
const int BTN_MODE = 8;
enum DeviceMode { MODE_INFO, MODE_WRITE, MODE_GAMEPAD };
DeviceMode currentMode = MODE_INFO;
int currentSlot = 0;
// Переменные логики
bool joyYToggled = false;
bool lastModeBtnState = HIGH;
//bool lastA = HIGH, lastB = HIGH, lastX = HIGH, lastY = HIGH;
unsigned long joySwPressedTime = 0;
bool isSwPressed = false;
void setup() {
Serial.begin(115200);
Keyboard.begin();
Mouse.begin();
lcd.init(); lcd.backlight();
pinMode(JOY_SW_PIN, INPUT_PULLUP);
pinMode(BTN_A, INPUT_PULLUP);
pinMode(BTN_B, INPUT_PULLUP);
pinMode(BTN_X, INPUT_PULLUP);
pinMode(BTN_Y, INPUT_PULLUP);
pinMode(BTN_MODE, INPUT_PULLUP);
// Раскомментируй строчку ниже ОДИН РАЗ, если нужно забить память тест-паролями
// fillEEPROMWithData();
updateDisplay();
}
void loop() {
checkModeButton();
if (currentMode == MODE_GAMEPAD) {
handleGamepadMode();
} else {
handlePasswordModes();
}
checkIncomingSerial();
}
// 2. РЕАЛИЗАЦИЯ ФУНКЦИЙ
void checkModeButton() {
bool state = digitalRead(BTN_MODE);
if (state == LOW && lastModeBtnState == HIGH) {
delay(50);
if (digitalRead(BTN_MODE) == LOW) {
currentMode = (DeviceMode)((currentMode + 1) % 3);
updateDisplay();
while(digitalRead(BTN_MODE) == LOW);
}
}
lastModeBtnState = state;
}
void handlePasswordModes() {
int yVal = analogRead(JOY_Y_PIN);
bool swVal = digitalRead(JOY_SW_PIN);
if (!joyYToggled) {
if (yVal < 200) { currentSlot = (currentSlot == 19) ? 0 : currentSlot + 1; joyYToggled = true; updateDisplay(); }
else if (yVal > 800) { currentSlot = (currentSlot == 0) ? 19 : currentSlot - 1; joyYToggled = true; updateDisplay(); }
}
if (yVal >= 400 && yVal <= 600) joyYToggled = false;
if (swVal == LOW) {
if (!isSwPressed) {
joySwPressedTime = millis();
isSwPressed = true;
}
if (isSwPressed && (millis() - joySwPressedTime > 2000)) {
lcd.clear(); lcd.print("Dumping script..");
//Keyboard.print(pythonScript);
int len = strlen_P(pythonScript);
for (int i = 0; i < len; i++) {
char c = pgm_read_byte_near(pythonScript + i);
Keyboard.print(c);
delay(1);
}
isSwPressed = false;
updateDisplay();
}
} else {
if (isSwPressed) {
if (millis() - joySwPressedTime > 50) {
if (currentMode == MODE_WRITE) {
sendPassword(currentSlot);
}
}
isSwPressed = false;
}
}
static bool lastA = HIGH, lastB = HIGH, lastX = HIGH, lastY = HIGH;
if (digitalRead(BTN_A) == LOW && lastA == HIGH) { delay(50); if(digitalRead(BTN_A)==LOW) sendPassword(0); }
if (digitalRead(BTN_B) == LOW && lastB == HIGH) { delay(50); if(digitalRead(BTN_B)==LOW) sendPassword(1); }
if (digitalRead(BTN_X) == LOW && lastX == HIGH) { delay(50); if(digitalRead(BTN_X)==LOW) sendPassword(2); }
if (digitalRead(BTN_Y) == LOW && lastY == HIGH) { delay(50); if(digitalRead(BTN_Y)==LOW) sendPassword(3); }
lastA = digitalRead(BTN_A); lastB = digitalRead(BTN_B);
lastX = digitalRead(BTN_X); lastY = digitalRead(BTN_Y);
}
void handleGamepadMode() {
int xVal = analogRead(JOY_X_PIN);
int yVal = analogRead(JOY_Y_PIN);
bool swVal = digitalRead(JOY_SW_PIN);
// 1. ДВИЖЕНИЕ МЫШИ
// Считаем отклонение от центра (0-1023, центр ~512)
int deltaX = xVal - 512;
int deltaY = yVal - 512;
// Если вышли за пределы мертвой зоны в 100 единиц
if (abs(deltaX) > 100 || abs(deltaY) > 100) {
// Масштабируем скорость (делим на 50, как у тебя, или подбираем экспериментально)
int mouseX = deltaX / 50;
// Инвертируем Y, если джойстик при отклонении "вперед" должен двигать курсор "вверх"
int mouseY = (deltaY / 50);
// Ограничиваем значения в безопасный диапазон [-128, 127]
mouseX = constrain(mouseX, -127, 127);
mouseY = constrain(mouseY, -127, 127);
// Двигаем курсор!
Mouse.move(mouseX, mouseY, 0);
}
// 2. КЛИК КНОПКИ ДЖОЙСТИКА (Левая Кнопка Мыши)
static bool lastSwVal = HIGH;
if (swVal == LOW && lastSwVal == HIGH) {
delay(50); // Дебаунс
if (digitalRead(JOY_SW_PIN) == LOW) {
// Имитируем полноценный клик (нажал и тут же отпустил)
Mouse.click(MOUSE_LEFT);
// Альтернатива, если нуженドラッグ (зажатие):
// Mouse.press(MOUSE_LEFT); -> а при отпускании кнопки вызывать Mouse.release(MOUSE_LEFT);
}
}
lastSwVal = swVal;
// 3. КЛАВИАТУРНЫЙ БЛОК (остается без изменений)
static bool lastA = HIGH, lastB = HIGH, lastX = HIGH, lastY = HIGH;
if (digitalRead(BTN_A) == LOW && lastA == HIGH) { delay(50); if(digitalRead(BTN_A)==LOW) Serial.println("KEY: TAB"); Keyboard.write(KEY_TAB); }
if (digitalRead(BTN_B) == LOW && lastB == HIGH) { delay(50); if(digitalRead(BTN_B)==LOW) Serial.println("KEY: SPACE"); Keyboard.write(' '); }
if (digitalRead(BTN_X) == LOW && lastX == HIGH) { delay(50); if(digitalRead(BTN_X)==LOW) Serial.println("KEY: ENTER"); Keyboard.write(KEY_RETURN); }
if (digitalRead(BTN_Y) == LOW && lastY == HIGH) { delay(50); if(digitalRead(BTN_Y)==LOW) Serial.println("KEY: ESC"); Keyboard.write(KEY_ESC); }
lastA = digitalRead(BTN_A); lastB = digitalRead(BTN_B);
lastX = digitalRead(BTN_X); lastY = digitalRead(BTN_Y);
//if (digitalRead(BTN_A) == LOW) { Serial.println("KEY: TAB"); Keyboard.write(KEY_TAB); }
//if (digitalRead(BTN_B) == LOW) { Serial.println("KEY: SPACE"); Keyboard.write(' '); }
//if (digitalRead(BTN_X) == LOW) { Serial.println("KEY: ENTER"); Keyboard.write(KEY_RETURN); }
//if (digitalRead(BTN_Y) == LOW) { Serial.println("KEY: ESC"); Keyboard.write(KEY_ESC); }
delay(10); // Задержку лучше уменьшить со 100 до 10-20 мс, чтобы мышь двигалась плавно, без рывков
}
void sendPassword(int idx) {
String pass = readPassword(idx);
if (pass == "") pass = "EmptySlot" + String(idx + 1);
Keyboard.print(pass);
if (currentMode == MODE_WRITE) {
lcd.setCursor(0, 1);
lcd.print("Typed Slot: "); lcd.print(idx + 1); lcd.print(" ");
delay(1200);
updateDisplay();
}
}
String readPassword(int idx) {
String p = "";
for (int i = 0; i < SLOT_SIZE; i++) {
char c = EEPROM.read(idx * SLOT_SIZE + i);
if (c == '\0' || c == 255) break;
p += c;
}
return p;
}
void checkIncomingSerial() {
if (Serial.available() > 0) {
String input = Serial.readStringUntil('\n');
input.trim();
if (input.startsWith("SET:")) {
int firstColon = input.indexOf(':');
int secondColon = input.indexOf(':', firstColon + 1);
if (firstColon != -1 && secondColon != -1) {
int slotIndex = input.substring(firstColon + 1, secondColon).toInt();
String newPass = input.substring(secondColon + 1);
if (slotIndex >= 0 && slotIndex <= 19 && newPass.length() < SLOT_SIZE) {
int startAddress = slotIndex * SLOT_SIZE;
int len = newPass.length();
for (int i = 0; i < SLOT_SIZE - 1; i++) {
if (i < len) EEPROM.update(startAddress + i, newPass[i]);
else EEPROM.update(startAddress + i, '\0');
}
EEPROM.update(startAddress + SLOT_SIZE - 1, '\0');
lcd.clear(); lcd.print("SAVED TO SLOT "); lcd.print(slotIndex + 1);
delay(1000); updateDisplay();
}
}
}
}
}
void updateDisplay() {
lcd.clear();
lcd.setCursor(0, 0);
switch(currentMode) {
case MODE_INFO:
lcd.print("MODE: [INFO]");
lcd.setCursor(0, 1);
{
String pass = readPassword(currentSlot);
if (pass == "") pass = "Empty " + String(currentSlot + 1);
lcd.print(currentSlot + 1); lcd.print(": "); lcd.print(pass.substring(0, 12));
}
break;
case MODE_WRITE:
lcd.print("MODE: [WRITE]");
lcd.setCursor(0, 1);
lcd.print("Select Slot: "); lcd.print(currentSlot + 1);
break;
case MODE_GAMEPAD:
lcd.print("MODE: [GAMEPAD]");
lcd.setCursor(0, 1);
lcd.print("Joy=Mouse 4B=HID");
break;
}
}
+11
View File
@@ -0,0 +1,11 @@
This directory is intended for PlatformIO Test Runner and project tests.
Unit Testing is a software testing method by which individual units of
source code, sets of one or more MCU program modules together with associated
control data, usage procedures, and operating procedures, are tested to
determine whether they are fit for use. Unit testing finds problems early
in the development cycle.
More information about PlatformIO Unit Testing:
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html