├── 3d_models
├── README.md
├── keyCap_1x1.stl
├── keyCap_2x1.stl
├── lid.stl
├── main_tran_housing.stl
└── recv_housing.stl
├── LICENSE.md
├── README.md
├── readme_imgs
├── attiny_stripboards.PNG
├── components.PNG
├── recv_wiring.png
├── thumbnail.png
├── tran_wiring.png
└── usbasp.PNG
├── receiver
└── Proj_Custom_Keyboard_ProMicro
│ └── Proj_Custom_Keyboard_ProMicro.ino
└── transmitter
└── Proj_Custom_Keyboard_Attiny
└── Proj_Custom_Keyboard_Attiny.ino
/3d_models/README.md:
--------------------------------------------------------------------------------
1 | # 3D models
2 |
3 | Please note, these models only work for MX Cherry switches.
--------------------------------------------------------------------------------
/3d_models/keyCap_1x1.stl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ProjectsWithRed/wireless_keyboard/74fc3b339c15f43a9e0a151d29aad03f54df9913/3d_models/keyCap_1x1.stl
--------------------------------------------------------------------------------
/3d_models/keyCap_2x1.stl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ProjectsWithRed/wireless_keyboard/74fc3b339c15f43a9e0a151d29aad03f54df9913/3d_models/keyCap_2x1.stl
--------------------------------------------------------------------------------
/3d_models/lid.stl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ProjectsWithRed/wireless_keyboard/74fc3b339c15f43a9e0a151d29aad03f54df9913/3d_models/lid.stl
--------------------------------------------------------------------------------
/3d_models/main_tran_housing.stl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ProjectsWithRed/wireless_keyboard/74fc3b339c15f43a9e0a151d29aad03f54df9913/3d_models/main_tran_housing.stl
--------------------------------------------------------------------------------
/3d_models/recv_housing.stl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ProjectsWithRed/wireless_keyboard/74fc3b339c15f43a9e0a151d29aad03f54df9913/3d_models/recv_housing.stl
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | 
This work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Arduino custom wireless keyboard
2 |
3 | There is a [video](https://youtu.be/N5rOW5Bu1kc) associated with this repo, I highly recommend you watch it if you are going to use this repo.
4 |
5 | [](https://youtu.be/N5rOW5Bu1kc "Arduino wireless keyboard")
6 |
7 | # How to use
8 |
9 | ## Libraries needed
10 |
11 | *Installed directly from the Arduino library manager.
12 |
13 | - `RF24` by TMRh20.
14 | - `Button` by Michael Adams.
15 |
16 | ## For the transmitter
17 |
18 | - This is the micro-controller (MC) that will be running on battery and where all the buttons will be connected to. This needs to be a low current consuming MC and one that ideally meets the number of inputs pins to match the number buttons you are going to have.
19 | - I highly recommend the Attiny MCs, such as the Attiny85 (8 pins), Attiny84 (14 pins), or the Attiny88 (28 pins).
20 | - Changes you need to make to the code (`/transmitter`):
21 | - The `CE and CSN` pin numbers to match your connections, these could be any GPIO pins in your MC.
22 | - `MAX_SHORTCUT_KEYS`, this is the maximum number of characters a keyboard shortcut/sequence can be. This is specified so only the required number of bytes are sent through the radio signal.
23 | - The `BUTTONS_INFO` array. Each button element is made up of two values, the first is the pin number the button is connected to your MC. The second is a string of characters seperated by spaces. The characters are represented by their decimal/int values, which can be found [here](http://www.asciitable.com/) and [here](https://www.arduino.cc/reference/en/language/functions/usb/keyboard/keyboardmodifiers/). Make sure you don't go over your `MAX_SHORTCUT_KEYS` in the string of keys, if more keys are required, simply increase `MAX_SHORTCUT_KEYS`.
24 |
25 |
26 | ## For the Receiver
27 |
28 | - Any MC can be used here with USB cable connection, and one that has HID support so you can easily use the Arduino Keyboard library with no issues. I recommend the Pro Micro MC.
29 | - Changes you need to make to the code (`/receiver`):
30 | - The only change you need to make is if you changed the `MAX_SHORTCUT_KEYS` in the transmitter side, if you did, make sure the `MAX_SHORTCUT_KEYS` matches.
31 |
32 |
33 |
34 | ## For 3D printing
35 |
36 | Please refer to the `/3d_models` directory.
37 |
38 |
39 | # Components
40 |
41 |
42 |
43 |
44 | # Wiring
45 |
46 | ## Transmitter
47 |
48 |
49 |
50 | ## Receiver
51 |
52 |
53 |
54 | # How to upload code to Attiny MCs
55 |
56 | - The Attiny MCs can be programmed just like any Arduino and it's very easy to upload code to them.
57 | - You just need a USBASP adapter, then simply make the connections as shown in the image below.
58 |
59 |
60 |
61 |
62 | - You will also need to install the Attiny boards using the [AttinyCore](https://github.com/SpenceKonde/ATTinyCore) board manager by placing this link `http://drazzy.com/package_drazzy.com_index.json` to your "Additional Boards Manager URLs", which can be accessed in `File > Preferences`.
63 |
64 | - From `Tools > Board`, choose your Attiny board with the no bootloader option.
65 | - Then go to `Tools > Programmer` and choose `USBasp (ATTinyCore)`, and then press `Tools > Burn Bootloader`.
66 | - Then to simply upload code, use `Sketch > Upload Using Programmer`.
67 |
68 | - You can use stripboards with some wires to make uploading code to the Attiny MCs more convenient:
69 |
70 |
71 |
--------------------------------------------------------------------------------
/readme_imgs/attiny_stripboards.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ProjectsWithRed/wireless_keyboard/74fc3b339c15f43a9e0a151d29aad03f54df9913/readme_imgs/attiny_stripboards.PNG
--------------------------------------------------------------------------------
/readme_imgs/components.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ProjectsWithRed/wireless_keyboard/74fc3b339c15f43a9e0a151d29aad03f54df9913/readme_imgs/components.PNG
--------------------------------------------------------------------------------
/readme_imgs/recv_wiring.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ProjectsWithRed/wireless_keyboard/74fc3b339c15f43a9e0a151d29aad03f54df9913/readme_imgs/recv_wiring.png
--------------------------------------------------------------------------------
/readme_imgs/thumbnail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ProjectsWithRed/wireless_keyboard/74fc3b339c15f43a9e0a151d29aad03f54df9913/readme_imgs/thumbnail.png
--------------------------------------------------------------------------------
/readme_imgs/tran_wiring.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ProjectsWithRed/wireless_keyboard/74fc3b339c15f43a9e0a151d29aad03f54df9913/readme_imgs/tran_wiring.png
--------------------------------------------------------------------------------
/readme_imgs/usbasp.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ProjectsWithRed/wireless_keyboard/74fc3b339c15f43a9e0a151d29aad03f54df9913/readme_imgs/usbasp.PNG
--------------------------------------------------------------------------------
/receiver/Proj_Custom_Keyboard_ProMicro/Proj_Custom_Keyboard_ProMicro.ino:
--------------------------------------------------------------------------------
1 | #include "SPI.h"
2 | #include "RF24.h"
3 |
4 | #include
5 |
6 | #define CE_PIN 5
7 | #define CSN_PIN 6
8 |
9 | RF24 radio(CE_PIN, CSN_PIN);
10 |
11 |
12 | uint8_t ADDRESS[6] = "CKeyB";
13 |
14 |
15 | // Maximum number of keys a shortcut can be, or max number of keys to send through the NRF24L01 per button.
16 | // This needs to match with the transmitter side.
17 | const int MAX_SHORTCUT_KEYS = 4;
18 |
19 |
20 | const int BTN_SHORTCUT_SIZE = (3 * MAX_SHORTCUT_KEYS) + (MAX_SHORTCUT_KEYS - 1) + 1;
21 |
22 | char btnShortcut[BTN_SHORTCUT_SIZE];
23 |
24 | char * key;
25 | int keyInt;
26 |
27 |
28 |
29 | void initRadio() {
30 | if (!radio.begin()) {
31 | while (1) {}
32 | }
33 |
34 | radio.setPALevel(RF24_PA_LOW);
35 | radio.setPayloadSize(BTN_SHORTCUT_SIZE);
36 | radio.openReadingPipe(1, ADDRESS);
37 | radio.setDataRate(RF24_1MBPS);
38 |
39 | radio.startListening();
40 | }
41 |
42 |
43 |
44 | void setup() {
45 | Keyboard.begin();
46 |
47 | initRadio();
48 | }
49 |
50 |
51 |
52 | void loop() {
53 | if (radio.available()) {
54 | radio.read(&btnShortcut, sizeof(btnShortcut));
55 |
56 | // Excract each key integer value from the incoming string and press each button.
57 | key = strtok(btnShortcut, " ");
58 |
59 | while(key != NULL) {
60 | keyInt = atoi(key);
61 | Keyboard.press(keyInt);
62 |
63 | key = strtok(NULL, " ");
64 | }
65 |
66 | delay(10);
67 | Keyboard.releaseAll();
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/transmitter/Proj_Custom_Keyboard_Attiny/Proj_Custom_Keyboard_Attiny.ino:
--------------------------------------------------------------------------------
1 | #include "SPI.h"
2 | #include "RF24.h"
3 |
4 | #include
5 |
6 |
7 | // Radio, choose any pins on your micro-controller to use as the CE and CSN pins.
8 | #define CE_PIN 3
9 | #define CSN_PIN 7
10 |
11 | const uint8_t ADDRESS[6] = "CKeyB";
12 |
13 |
14 | // Maximum number of keys a shortcut can be, or max number of keys to send through the NRF24L01 per button.
15 | // This needs to match with the receiver side.
16 | const int MAX_SHORTCUT_KEYS = 4;
17 |
18 |
19 | const int BTN_SHORTCUT_SIZE = (3 * MAX_SHORTCUT_KEYS) + (MAX_SHORTCUT_KEYS - 1) + 1;
20 |
21 | struct ButtonInfo {
22 | int btnPin;
23 | char btnShortcut[BTN_SHORTCUT_SIZE];
24 | };
25 |
26 |
27 | // All keys are represented using their ASCII decimal/int value. This can be found here: www.asciitable.com
28 | // First specify the pin number, then seperate each key for that button in a string by a space.
29 | const ButtonInfo BUTTONS_INFO[] = {{2, "80 119 82"},
30 | {1, "128 99"},
31 | {0, "128 118"},
32 | };
33 |
34 |
35 | const int N_BUTTONS = sizeof(BUTTONS_INFO) / sizeof(BUTTONS_INFO[0]);
36 |
37 | const uint16_t DEBOUNCE_MS = 10;
38 |
39 |
40 | RF24 radio(CE_PIN, CSN_PIN);
41 |
42 |
43 | Button *buttonObjs[N_BUTTONS];
44 |
45 |
46 |
47 | void initRadio() {
48 |
49 | if (!radio.begin()) {
50 | while (1) {}
51 | }
52 |
53 | radio.setPALevel(RF24_PA_LOW);
54 | radio.setPayloadSize(BTN_SHORTCUT_SIZE);
55 | radio.openWritingPipe(ADDRESS);
56 | radio.setDataRate(RF24_1MBPS);
57 |
58 | radio.stopListening();
59 | }
60 |
61 | void initButtons() {
62 | for(int i = 0; i < N_BUTTONS; i++) {
63 | ButtonInfo btnInfo = BUTTONS_INFO[i];
64 | buttonObjs[i] = new Button(btnInfo.btnPin, DEBOUNCE_MS);
65 | buttonObjs[i] -> begin();
66 | }
67 | }
68 |
69 |
70 | void setup() {
71 |
72 | initRadio();
73 | initButtons();
74 |
75 | }
76 |
77 | void loop() {
78 |
79 | // If any button pressed, then send the button keys through radio using the nRF24L01.
80 | for(int i = 0; i < N_BUTTONS; i++) {
81 | if(buttonObjs[i] -> pressed()) {
82 | ButtonInfo btnInfo = BUTTONS_INFO[i];
83 |
84 | radio.write(&btnInfo.btnShortcut, sizeof(btnInfo.btnShortcut));
85 |
86 | break;
87 | }
88 | }
89 | }
90 |
--------------------------------------------------------------------------------