From edbfd0adb48ed3f63f1de3208518bad96c74aca5 Mon Sep 17 00:00:00 2001 From: Dooho Yi Date: Sun, 9 Apr 2023 20:43:00 +0900 Subject: [PATCH] 2 dimensional + polyphonic rewrite of ringringrain. (Rev.2) --- arduino/rainboard/rainboard.ino | 1 + arduino/rainboard/src/rainboard.ino | 175 ++++++++----- ringringrain_piano_node.pd | 26 ++ ringringrain_rev2.pd | 378 ++++++++++++++++++++++++++++ 4 files changed, 511 insertions(+), 69 deletions(-) create mode 120000 arduino/rainboard/rainboard.ino create mode 100644 ringringrain_piano_node.pd create mode 100644 ringringrain_rev2.pd diff --git a/arduino/rainboard/rainboard.ino b/arduino/rainboard/rainboard.ino new file mode 120000 index 0000000..e816499 --- /dev/null +++ b/arduino/rainboard/rainboard.ino @@ -0,0 +1 @@ +src/rainboard.ino \ No newline at end of file diff --git a/arduino/rainboard/src/rainboard.ino b/arduino/rainboard/src/rainboard.ino index 1f85e8b..7e670cd 100644 --- a/arduino/rainboard/src/rainboard.ino +++ b/arduino/rainboard/src/rainboard.ino @@ -1,38 +1,62 @@ +// +// a 2-dimensional ringringrain touch-pad(board) +// +// D. Yi @ 2023 4 9 +// + +////network! + #include -#include const char* ssid = "nolink2"; const char* password = "2222277777"; const int NETWORK_PORT = 27016; -//// A UDP instance to let us send and receive packets over UDP -//WiFiUDP Udp; -//const IPAddress outIp(192,168,43,13); // remote IP (not needed for receive) -//const unsigned int outPort = 9999; // remote port (not needed for receive) -//const unsigned int localPort = 8888; // local port to listen for UDP packets (here's where we send the packets) - - #include #include "utility/WiFiClientStream.h" #include "utility/WiFiServerStream.h" WiFiServerStream serverStream(NETWORK_PORT); -std::vector pins = {16, 15, 17, 18, 20, 19, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33}; //16 -//2 ==> flipping autonomously 1/0 without grounding! (maybe grounded by something else???) -//1, 3, 4, 5, 6, 7, 8, ==> flipping 1/0 ... while grounded manually. +////pad structure -//i have a feeling ... this relates to 'touch sensing'... this precise flipping might be from cap. charge/discharge cycles? +#define NUMKEYS 42 // columns : 14, rows : 3 +// --> how many keys are available for this pad + +int keystat[NUMKEYS] = {0, }; +// --> a buffer to store statuses of all keys +// --> needed to extract only 'the change' of key statuses + +#define MAXCHANGES 10 +int keychanges[MAXCHANGES] = {0, }; +int n_keychg = 0; +// --> for monitoring only 'changed' keys. + +#define NUMCOLS 14 +int pins_cols[NUMCOLS] = {19, 20, 18, 17, 15, 16, 40, 39, 38, 37, 36, 35, 34, 33}; //16 +// --> cols is horizontal offsets on the board +// --> to be read as input. + +#define NUMROWS 3 +int pins_rows[NUMROWS] = {6, 7, 8}; +// --> rows is vertical offsets on the board +// --> to be driven as output. void setup() { - //pinmodes - for (int idx = 0; idx < pins.size(); idx++) { - pinMode(pins[idx], INPUT_PULLUP); - } - //serial Serial.begin(115200); + //pinmodes + // rows : to be driven as output. (scanning) + for (int idx = 0; idx < NUMROWS; idx++) { + pinMode(pins_rows[idx], OUTPUT); + digitalWrite(pins_rows[idx], HIGH); + } + // cols : to be read as input. (PULL-UP) + for (int idx = 0; idx < NUMCOLS; idx++) { + pinMode(pins_cols[idx], INPUT_PULLUP); + } + //wifi WiFi.mode(WIFI_STA); // Connect to WiFi network @@ -55,63 +79,76 @@ void setup() //firmata Firmata.disableBlinkVersion(); Firmata.begin(serverStream); - -// Firmata.begin(115200); -// Firmata.setFirmwareNameAndVersion("ConfigurableFirmata", FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION); } void loop() { - for (int idx = 0; idx < pins.size(); idx++) { - Firmata.sendAnalog(idx, digitalRead(pins[idx])*1023); + // perform a full scan of the key statuses! + + // update row voltages + static int row = 0; + digitalWrite(pins_rows[row], HIGH); // let old 'on' row goes 'off' first. + row++; + if (row >= NUMROWS) { + row = 0; } + digitalWrite(pins_rows[row], LOW); // let new 'off' row goes 'on'.. -> ready to scan. + + // 100us ~ 200us, waiting for the electricity ready... + delayMicroseconds(200); + + // read all cols + for (int col = 0; col < NUMCOLS; col++) { + int key = row * NUMCOLS + col; + if (key < NUMKEYS) { + int cur_key = !digitalRead(pins_cols[col]); //logic inversion. (HIGH = noteoff, LOW = noteon.) + + // if it is 'changed', + if (cur_key != keystat[key]) { + // if there is a room to record this change, + if (n_keychg < MAXCHANGES) { + // make a memo. + int keycoded = (key) * 10 + cur_key; // for example : C4 note-on --> 601 ( == 60*10 + 1) + keychanges[n_keychg] = keycoded; + n_keychg++; + // send Firmata msg. over WIFI. + Firmata.sendAnalog(0, keycoded); + //@Pd + //[pduino/arduino] will divide this by 1023.0 to map 0-1023 -> 0.0-1.0 + //so, to recover original values, multiply back by 1023.0. + } + } + + // okay. good. now, apply the change. + keystat[key] = cur_key; + } + } + + // at the moment of 'full scan done' + if (row == NUMROWS - 1) { + + // // print out the buffer status. + // for (int key = 0; key < NUMKEYS; key++) { + // Serial.print(keystat[key]); Serial.print(" "); + // } + // Serial.println(); + + // // print out the changes. + // for (int chg = 0; chg < n_keychg; chg++) { + // Serial.print(keychanges[chg]); + // Serial.println(); + // } + + // clear 'keychanges' array + for (int idx = 0; idx < MAXCHANGES; idx++) { + keychanges[idx] = 0; + n_keychg = 0; + } + + } + // + // // discard all incoming MIDI msgs. + // while (usbMIDI.read()) { } serverStream.maintain(); } - - -// [NOTE] -// because firmata analog way has limits of max. channels <= 16. you can use digital way.. like below. -// but this not yet confirmed whether it is working or not. -// - -// #include - -// int pins_port0[8] = {17, 18, 2, 3, 4, 5, 6, 7}; -// int pins_port1[8] = {8, 9, 10, 11, 12, 24, 25, 26}; -// int pins_port2[8] = {27, 28, 29, 30, 31, 32, 33, 33}; - -// void setup() -// { -// for (int idx = 0; idx < 8; idx++) pinMode(pins_port0[idx], INPUT_PULLUP); -// for (int idx = 0; idx < 8; idx++) pinMode(pins_port1[idx], INPUT_PULLUP); -// for (int idx = 0; idx < 8; idx++) pinMode(pins_port2[idx], INPUT_PULLUP); - -// Firmata.setFirmwareNameAndVersion("ConfigurableFirmata", FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION); -// Firmata.begin(115200); -// } - -// void loop() -// { -// byte port = 0; - -// static byte port0_prev = 0; -// port = 0x00; -// for (int idx = 0; idx < 8; idx++) port |= (digitalRead(pins_port0[idx]) ? 0x01<