commit 7b1d78c13fa5b69c316847a3caf6bb4a4875ca48 Author: Valentin Boettcher Date: Sat Aug 14 00:26:54 2021 +0200 init diff --git a/keyboard/keyboard.ino b/keyboard/keyboard.ino new file mode 100644 index 0000000..da3c963 --- /dev/null +++ b/keyboard/keyboard.ino @@ -0,0 +1,183 @@ +/*****************************************************************************/ +/* Pins */ +/*****************************************************************************/ + +// columns +constexpr int KD1 = 14; +constexpr int KD2 = 15; +constexpr int KD3 = 16; +constexpr int KD4 = 17; +constexpr int KD5 = 18; +constexpr int KD6 = 19; +constexpr int KD7 = 2; +constexpr int KD8 = 3; + +// row selectors +constexpr int SA1 = 4; +constexpr int SA2 = 5; +constexpr int SA3 = 6; + +constexpr int SEL_A = SA1; +constexpr int SEL_B = SA2; +constexpr int SEL_C = SA3; + +// range selector +constexpr int SA4 = 7; +constexpr int SA5 = 8; + +constexpr int RS1 = SA4; +constexpr int RS2 = SA5; + +/*****************************************************************************/ +/* Convenience */ +/*****************************************************************************/ +constexpr int col_pins[] = {KD1, KD2, KD3, KD4, KD5, KD6, KD7, KD8}; +constexpr int num_col_pins = 8; +constexpr int num_half_pins = 4; + +// first hit +constexpr int first_col[] = {KD1, KD2, KD3, KD4}; + +// second hit +constexpr int second_col[] = { KD5, KD6, KD7, KD8 }; + +constexpr int selector_pins[] = {SA1, SA2, SA3, SA4, SA5}; +constexpr int num_selector_pins = 5; + +enum Range { LO = 0, MID, HI}; +constexpr Range ranges[] = {Range::LO, Range::MID, Range::HI}; + +// rows in range +constexpr int rows [] = {8, 8, 6}; +constexpr int range_offsets [] = {0, + rows[1] * num_half_pins, + rows[0] * num_half_pins + rows[1] * num_half_pins}; + +/*****************************************************************************/ +/* Keys/Notes */ +/*****************************************************************************/ +constexpr int midi_base = 21; +constexpr int num_keys = 88; + +/*****************************************************************************/ +/* Velocity */ +/*****************************************************************************/ +constexpr double min_velocity = 0.00005; +constexpr double max_velocity = 0.00030; + +/*****************************************************************************/ +/* Keyscanning */ +/*****************************************************************************/ + +void select_range(Range range) { + switch(range) { + case Range::LO: + digitalWrite(RS1, LOW); + digitalWrite(RS2, LOW); + break; + + case Range::MID: + digitalWrite(RS1, HIGH); + digitalWrite(RS2, LOW); + break; + + case Range::HI: + digitalWrite(RS1, LOW); + digitalWrite(RS2, HIGH); + break; + } +} + +void select_row(int row) { + digitalWrite(SEL_A, row & 1); + + row >>= 1; + digitalWrite(SEL_B, row & 1); + + row >>= 1; + digitalWrite(SEL_C, row & 1); +} + +// UNUSED +/* int scan_row(bool second) { */ +/* const int (&pins)[num_half_pins] = second ? second_col : first_col; */ + +/* for(int i= 0; i < num_half_pins; i++) { */ +/* if (!digitalRead(pins[i])) */ +/* return i; */ +/* } */ + +/* return -1; */ +/* } */ + +int get_midi_note(Range range, int row, int col) { + return midi_base + row * num_half_pins + col + range_offsets[range]; +} + +char midi_velocity(double velocity) { + return (constrain(velocity, min_velocity, max_velocity) - min_velocity) / max_velocity * 127; +} + +unsigned long S1[num_keys]; // timer value for first hit or 0 +bool S2[num_keys]; // whether key is pressed + +void setup() { + /***************************************************************************/ + /* Serial */ + /***************************************************************************/ + Serial.begin(9600); + + /***************************************************************************/ + /* Pins */ + /***************************************************************************/ + for (int i = 0; i < num_col_pins; i++) { + pinMode(col_pins[i], INPUT_PULLUP); + } + + for (int i = 0; i < num_selector_pins; i++) { + pinMode(selector_pins[i], OUTPUT); + } + + for (int i = 0; i < num_keys; i++) { + S2[i] = false; + } + + digitalWrite(RS1, LOW); + digitalWrite(RS2, LOW); + digitalWrite(SEL_A, LOW); + digitalWrite(SEL_B, LOW); + digitalWrite(SEL_C, LOW); +} + + +void loop() { + int key = 0; + + for (const auto range : ranges) { + select_range(range); + + for (int row = 0; row < rows[range]; row++) { + select_row(row); + + // read first row + for(int i= 0; i < num_half_pins; i++) { + if (!digitalRead(first_col[i])) { + if(S1[key] == 0) { + S1[key] = micros(); + } else { + if (!S2[key] && !digitalRead(second_col[i])) { + S2[key] = true; + + auto velocity = 1/static_cast(micros() - S1[key]); + Serial.print(key); + Serial.print(" "); + Serial.println(midi_velocity(velocity), DEC); + } + } + } + + key++; + } + } + } +} diff --git a/project.org b/project.org new file mode 100644 index 0000000..501e225 --- /dev/null +++ b/project.org @@ -0,0 +1,18 @@ +* Pinout +| Header | Arduino | Name | Function | Color | +|--------+---------+------+----------+--------| +| 1 | A0 | KD1 | S1 | | +| 2 | A1 | KD2 | S1 | | +| 3 | A2 | KD3 | S1 | | +| 4 | A3 | KD4 | S1 | | +| 5 | A4 | KD5 | S2 | Red | +| 6 | A5 | KD6 | S2 | Grey | +| 7 | D2 | KD7 | S2 | Yellow | +| 8 | D3 | KD8 | S2 | Purple | +| 9 | D4 | SA1 | Select A | White | +| 10 | D5 | SA2 | Select B | Black | +| 11 | D6 | SA3 | Select C | Blue | +| 12 | D7 | SA4 | Mult 1 | Orange | +| 13 | D8 | SA5 | Mult 2 | Black | +| 14 | 5V | 5V | | White | +| 15 | GND | GND | | Yellow | diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..6cf1533 --- /dev/null +++ b/shell.nix @@ -0,0 +1,4 @@ +{ pkgs ? import {} }: +pkgs.mkShell { + nativeBuildInputs = with pkgs; [ arduino git arduino-cli picocom ]; +} diff --git a/upload.sh b/upload.sh new file mode 100755 index 0000000..8c73e24 --- /dev/null +++ b/upload.sh @@ -0,0 +1,3 @@ +#! /usr/bin/env bash +sudo arduino-cli compile -v -p /dev/ttyUSB0 -b arduino:avr:nano:cpu=atmega328old keyboard +sudo arduino-cli upload -v -p /dev/ttyUSB0 -b arduino:avr:nano:cpu=atmega328old keyboard