[M] Rename project

This commit is contained in:
Hykilpikonna
2023-04-20 21:05:24 -04:00
parent 60ac01d661
commit 24574897ec
10 changed files with 0 additions and 0 deletions
+7
View File
@@ -0,0 +1,7 @@
.pio
CMakeListsPrivate.txt
cmake-build-*/
.idea
.DS_Store
._*
+33
View File
@@ -0,0 +1,33 @@
# !!! WARNING !!! AUTO-GENERATED FILE, PLEASE DO NOT MODIFY IT AND USE
# https://docs.platformio.org/page/projectconf/section_env_build.html#build-flags
#
# If you need to override existing CMake configuration or add extra,
# please create `CMakeListsUser.txt` in the root of project.
# The `CMakeListsUser.txt` will not be overwritten by PlatformIO.
cmake_minimum_required(VERSION 3.13)
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_C_COMPILER_WORKS 1)
set(CMAKE_CXX_COMPILER_WORKS 1)
project("untitled" C CXX)
include(CMakeListsPrivate.txt)
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/CMakeListsUser.txt)
include(CMakeListsUser.txt)
endif()
add_custom_target(
Production ALL
COMMAND platformio -c clion run "$<$<NOT:$<CONFIG:All>>:-e${CMAKE_BUILD_TYPE}>"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
add_custom_target(
Debug ALL
COMMAND platformio -c clion debug "$<$<NOT:$<CONFIG:All>>:-e${CMAKE_BUILD_TYPE}>"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
add_executable(Z_DUMMY_TARGET ${SRC_LIST})
+43
View File
@@ -0,0 +1,43 @@
# Taiko-stick / 太鼓槌
A pair of drumsticks that can be used to play Taiko no Tatsujin on any surface.
一对可以在任何表面上打太鼓达人的鼓槌.
## 1. Build / 制作
### Materials Required / 材料
* 2x Thick-enough drumsticks
(The one I used: [taobao link](https://item.taobao.com/item.htm?id=665108049486))
* 2x Piezo sensors (压电/蜂鸣陶瓷片)
* 2x 1MΩ resistors
* 1x Arduino Nano
(or any other dev board, just change the platformio config)
* Many wires
### Tools Required / 工具
* Either a breadboard, SPL2 solder-less connectors, or a soldering kit
* A computer
### Connections / 连接
![img.png](doc/img.png)
## 2. Run / 运行
### Flash Firmware / 烧录固件
1. Install PlatformIO Core ([Guide](https://platformio.org/install/cli))
2. Connect the Arduino Nano to your computer
3. Upload firmware using `platformio run --target upload`
### Run Backend / 运行后端
I'm too lazy to write a HID device driver, so I'm using a python script to read the serial output from the Arduino and send keystrokes to the computer.
1. Install Python 3.11+ ([Guide](https://www.python.org/downloads/))
2. Install dependencies using `pip install -r requirements.txt`
3. Run `python reader.py`
4. Use `Ctrl+C` to exit.
+69
View File
@@ -0,0 +1,69 @@
"""
This script reads the Arduino's serial output and convert it to keyboard input.
Requirements: pip install pyserial keyboard matplotlib
"""
import time
import keyboard
import serial.tools.list_ports
TAIKO_KEYS = ['f', 'd']
if __name__ == '__main__':
# List serial ports
ports = serial.tools.list_ports.comports()
# If there are no ports, exit
if not ports:
print('No serial ports found!')
exit(1)
# If there are more than one serial port, print them out
if len(ports) > 1:
print('Multiple serial ports found:')
for i, port in enumerate(ports):
print(f'[{i}] {port.device}')
print()
# Ask the user to select one
inp = input('Select a port: ')
port = ports[int(inp)].device
# If there is only one serial port, use it
else:
port = ports[0].device
# Open the serial port
print(f'Opening serial port {port}...')
ser = serial.Serial(port, 115200)
# Read the serial port
try:
start_time = time.time()
while True:
line = ser.readline().decode('utf-8', errors='ignore').strip()
print(line)
# If the line starts with ";", it's a plot point
if line.startswith(';'):
line = line[1:].split(';')
ys = [float(y) / 1024.0 for y in line]
yleft, yright = ys
# If the line starts with ":", it's a keyboard input
elif line.startswith('Hit:'):
# Index of the drumstick that hit the piezo
line = line[4:]
cmd = line[0]
key = TAIKO_KEYS[int(line[1:])]
if cmd == "+":
keyboard.press(key)
elif cmd == "-":
keyboard.release(key)
except KeyboardInterrupt:
ser.close()
print('Closed serial port.')
Binary file not shown.

After

Width:  |  Height:  |  Size: 14 MiB

+39
View File
@@ -0,0 +1,39 @@
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 usual convention is to give header files names that end with `.h'.
It is most portable to use only letters, digits, dashes, and underscores in
header file names, and at most one dot.
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 executable file.
The source code of each library should be placed in a an own separate directory
("lib/your_library_name/[here are source files]").
For example, see a structure of the following two libraries `Foo` and `Bar`:
|--lib
| |
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| | |- library.json (optional, 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
and a contents of `src/main.c`:
```
#include <Foo.h>
#include <Bar.h>
int main (void)
{
...
}
```
PlatformIO Library Dependency Finder will find automatically dependent
libraries scanning project source files.
More information about PlatformIO Library Dependency Finder
- https://docs.platformio.org/page/librarymanager/ldf.html
+14
View File
@@ -0,0 +1,14 @@
; 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:nanoatmega328new]
platform = atmelavr
board = nanoatmega328new
framework = arduino
+2
View File
@@ -0,0 +1,2 @@
pyserial
keyboard
+81
View File
@@ -0,0 +1,81 @@
#include <Arduino.h>
#define val const auto
#define let auto
/**
* Since the arduino library doesn't have printf, we have to make our own
*/
void send(const char* format, ...)
{
char buffer[512];
va_list args;
va_start(args, format);
vsnprintf(buffer, sizeof(buffer), format, args);
va_end(args);
Serial.println(buffer);
}
const int NUM_DRUMSTICKS = 2;
const int DRUMSTICK_PINS[] = {A0, A1};
int LAST_VALUES[] = {0, 0};
unsigned long LAST_HIT_TIMES[] = {0, 0};
// Values range from 0 to 1023, but since we reduced the resolution to 8 bits, we need to divide by 8
// After the division, values range from 0 to 127
val threshold = (int) (0.7 * 127);
// Minimum time between two hits
// This is to prevent falsely detecting the bouncing force as a hit
val bounce_delay = 5;
void setup()
{
Serial.begin(115200);
for (val pin: DRUMSTICK_PINS) pinMode(pin, INPUT);
send("Initialized");
}
void loop()
{
val time = millis();
// Loop through all the pins, indexed
for (let i = 0; i < NUM_DRUMSTICKS; i++)
{
val pin = DRUMSTICK_PINS[i];
val value = analogRead(pin) / 8;
val last = LAST_VALUES[i];
LAST_VALUES[i] = value;
// If the value is different from the last value, update it
if (value != last)
{
// Check last hit time
val last_hit_time = LAST_HIT_TIMES[i];
if (time - last_hit_time < bounce_delay)
continue;
// If it's greater than the threshold
if (value > threshold)
{
send(";%d;%d", i, value);
// If the last value was less than the threshold, it means the drumstick was just hit
if (last < threshold)
send("Hit:+%d", i);
}
else
{
// If the last value was greater than the threshold, it means the drumstick was just released
if (last > threshold)
{
send("Hit:-%d", i);
LAST_HIT_TIMES[i] = time;
}
}
}
}
}