From d94fed811bd7de6b1c5c1479668b8c619334c8cd Mon Sep 17 00:00:00 2001 From: Lukas Date: Thu, 14 Feb 2013 02:59:15 +0100 Subject: [PATCH] added libraries and clean up --- fritzing_files/input_Platte.fzz | Bin 0 -> 51402 bytes .../INPUT_MCP23017_test.ino | 28 +++++ source/MCP23017_test/MCP23017_test.ino | 99 +++++++++++++++ .../testing => _4051_test}/_4051_test.ino | 1 + .../input_4051_library_test.ino | 22 ++++ .../INPUT_74HC4051/INPUT_74HC4051.cpp | 67 ++++++++++ .../libraries/INPUT_74HC4051/INPUT_74HC4051.h | 29 +++++ .../INPUT_MCP23017/INPUT_MCP23017.cpp | 115 ++++++++++++++++++ .../libraries/INPUT_MCP23017/INPUT_MCP23017.h | 51 ++++++++ source/library/input_4051/input_4051.cpp | 42 ------- source/library/input_4051/input_4061.h | 28 ----- .../midi_in_out.ino} | 0 .../midi_in_out_softwareserial.ino | 62 ++++++++++ source/midi_led/midi_led.ino | 45 +++++++ source/piezo_input/piezo_input.ino | 9 ++ .../testing/midi_in_out_softwareserial.ino | 92 -------------- 16 files changed, 528 insertions(+), 162 deletions(-) create mode 100644 fritzing_files/input_Platte.fzz create mode 100644 source/INPUT_MCP23017_test/INPUT_MCP23017_test.ino create mode 100644 source/MCP23017_test/MCP23017_test.ino rename source/{sketches/testing => _4051_test}/_4051_test.ino (99%) create mode 100644 source/input_4051_library_test/input_4051_library_test.ino create mode 100644 source/libraries/INPUT_74HC4051/INPUT_74HC4051.cpp create mode 100644 source/libraries/INPUT_74HC4051/INPUT_74HC4051.h create mode 100644 source/libraries/INPUT_MCP23017/INPUT_MCP23017.cpp create mode 100644 source/libraries/INPUT_MCP23017/INPUT_MCP23017.h delete mode 100644 source/library/input_4051/input_4051.cpp delete mode 100644 source/library/input_4051/input_4061.h rename source/{sketches/testing/MIDI-Out_MCP23017.ino => midi_in_out/midi_in_out.ino} (100%) create mode 100644 source/midi_in_out_softwareserial/midi_in_out_softwareserial.ino create mode 100644 source/midi_led/midi_led.ino create mode 100644 source/piezo_input/piezo_input.ino delete mode 100644 source/sketches/testing/midi_in_out_softwareserial.ino diff --git a/fritzing_files/input_Platte.fzz b/fritzing_files/input_Platte.fzz new file mode 100644 index 0000000000000000000000000000000000000000..d53fea5ad32bab41d17089c4bd93c93a6f34cb64 GIT binary patch literal 51402 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 literal 0 HcmV?d00001 diff --git a/source/INPUT_MCP23017_test/INPUT_MCP23017_test.ino b/source/INPUT_MCP23017_test/INPUT_MCP23017_test.ino new file mode 100644 index 0000000..7bf3701 --- /dev/null +++ b/source/INPUT_MCP23017_test/INPUT_MCP23017_test.ino @@ -0,0 +1,28 @@ +#include + +#include +#include + +INPUT_MCP23017 input_MCP23017; +INPUT_74HC4051 input_4051; + +void setup() { + Serial.begin(9600); + input_MCP23017.begin(0,printValue); + input_4051.begin(A0,11,12,13,printValue); +} + +void loop() { + input_MCP23017.loop(); + input_4051.loop(); +} + +void printValue(int id, int pin, int value) { + Serial.print("id: "); + Serial.print(id); + Serial.print(" pin: "); + Serial.print(pin); + Serial.print(" value: "); + Serial.print(value); + Serial.println(); +} diff --git a/source/MCP23017_test/MCP23017_test.ino b/source/MCP23017_test/MCP23017_test.ino new file mode 100644 index 0000000..61d3c58 --- /dev/null +++ b/source/MCP23017_test/MCP23017_test.ino @@ -0,0 +1,99 @@ +#include + +#define MCP23017_ADDRESS 0x20 + +// registers (from https://github.com/adafruit/Adafruit-MCP23017-Arduino-Library/blob/master/Adafruit_MCP23017.h) +#define MCP23017_IODIRA 0x00 +#define MCP23017_IPOLA 0x02 +#define MCP23017_GPINTENA 0x04 +#define MCP23017_DEFVALA 0x06 +#define MCP23017_INTCONA 0x08 +#define MCP23017_IOCONA 0x0A +#define MCP23017_GPPUA 0x0C +#define MCP23017_INTFA 0x0E +#define MCP23017_INTCAPA 0x10 +#define MCP23017_GPIOA 0x12 +#define MCP23017_OLATA 0x14 + +#define MCP23017_IODIRB 0x01 +#define MCP23017_IPOLB 0x03 +#define MCP23017_GPINTENB 0x05 +#define MCP23017_DEFVALB 0x07 +#define MCP23017_INTCONB 0x09 +#define MCP23017_IOCONB 0x0B +#define MCP23017_GPPUB 0x0D +#define MCP23017_INTFB 0x0F +#define MCP23017_INTCAPB 0x11 +#define MCP23017_GPIOB 0x13 +#define MCP23017_OLATB 0x15 + +int _addr = 0; +int _value[16]; + +void setup() { + Serial.begin(9600); + Wire.begin(); + + // set defaults! + Wire.beginTransmission(MCP23017_ADDRESS | _addr); + Wire.write((byte)MCP23017_IODIRA); + Wire.write(0xFF); // all inputs on port A + Wire.endTransmission(); + + Wire.beginTransmission(MCP23017_ADDRESS | _addr); + Wire.write(MCP23017_IODIRB); + Wire.write(0xFF); // all inputs on port B + Wire.endTransmission(); + + + Wire.beginTransmission(MCP23017_ADDRESS | _addr); + Wire.write(MCP23017_GPPUA); + Wire.write(0xFF); // all pullup resistors on port A + Wire.endTransmission(); + + Wire.beginTransmission(MCP23017_ADDRESS | _addr); + Wire.write(MCP23017_GPPUB); + Wire.write(0xFF); // all pullup resistors on port B + Wire.endTransmission(); +} + +void loop() { + uint8_t pin,bank; + int value; + //read bank A + Wire.beginTransmission(MCP23017_ADDRESS | _addr); + Wire.write(MCP23017_GPIOA); + Wire.endTransmission(); + Wire.requestFrom(MCP23017_ADDRESS | _addr, 1); + bank = Wire.read(); + for (pin=0; pin<8; pin++) { + value = (bank >> pin) & 0x1; + if (_value[pin] != value) { + _value[pin] = value; + printValue(_addr,pin,value); + } + } + //read bank B + Wire.beginTransmission(MCP23017_ADDRESS | _addr); + Wire.write(MCP23017_GPIOB); + Wire.endTransmission(); + Wire.requestFrom(MCP23017_ADDRESS | _addr, 1); + bank = Wire.read(); + for (pin=8; pin<16; pin++) { + value = (bank >> (pin-8)) & 0x1; + if (_value[pin] != value) { + _value[pin] = value; + printValue(_addr,pin,value); + } + } +} + +void printValue(int id, int pin, int value) { + Serial.print("id: "); + Serial.print(id); + Serial.print(" pin: "); + Serial.print(pin); + Serial.print(" value: "); + Serial.print(value); + Serial.println(); +} diff --git a/source/sketches/testing/_4051_test.ino b/source/_4051_test/_4051_test.ino similarity index 99% rename from source/sketches/testing/_4051_test.ino rename to source/_4051_test/_4051_test.ino index 8b6d7bb..f02c5ab 100644 --- a/source/sketches/testing/_4051_test.ino +++ b/source/_4051_test/_4051_test.ino @@ -40,3 +40,4 @@ void loop() { Serial.println(); } } + diff --git a/source/input_4051_library_test/input_4051_library_test.ino b/source/input_4051_library_test/input_4051_library_test.ino new file mode 100644 index 0000000..8a42579 --- /dev/null +++ b/source/input_4051_library_test/input_4051_library_test.ino @@ -0,0 +1,22 @@ +#include + + + +INPUT_4051 input_4051(A1,10,9,8,printValue); + +void setup() { + Serial.begin(9600); + input_4051.setPinCount(2); +} + +void loop() { + input_4051.loop(); +} + +void printValue(int pin, int value) { + Serial.print("pin"); + Serial.print(pin); + Serial.print(" : "); + Serial.print(value/8); + Serial.println(); +} diff --git a/source/libraries/INPUT_74HC4051/INPUT_74HC4051.cpp b/source/libraries/INPUT_74HC4051/INPUT_74HC4051.cpp new file mode 100644 index 0000000..06aacc2 --- /dev/null +++ b/source/libraries/INPUT_74HC4051/INPUT_74HC4051.cpp @@ -0,0 +1,67 @@ +#include "Arduino.h" +#include "INPUT_74HC4051.h" + +void INPUT_74HC4051::begin(uint8_t analog, uint8_t s0, uint8_t s1, uint8_t s2,CallbackFunction cbF) { + _analog = analog; + + _s0 = s0; + _s1 = s1; + _s2 = s2; + + pinMode(_analog,INPUT); + + pinMode(_s0,OUTPUT); + pinMode(_s1,OUTPUT); + pinMode(_s2,OUTPUT); + + _callbackFunction = cbF; + + //init start values + uint8_t pin,r0,r1,r2; + for (pin=0; pin<8; pin++) { + r0 = bitRead(pin,0); + r1 = bitRead(pin,1); + r2 = bitRead(pin,2); + digitalWrite(_s0, r0); + digitalWrite(_s1, r1); + digitalWrite(_s2, r2); + //delayMicroseconds(10); + _value[pin] = analogRead(_analog); + } +} + +void INPUT_74HC4051::loop() { + uint8_t pin,r0,r1,r2; + int value; + for (pin=0; pin<8; pin++) { + r0 = bitRead(pin,0); + r1 = bitRead(pin,1); + r2 = bitRead(pin,2); + digitalWrite(_s0, r0); + digitalWrite(_s1, r1); + digitalWrite(_s2, r2); + //delayMicroseconds(10); + value = analogRead(_analog); + if (_value[pin] < value - INPUT_74HC4051_TOLERANCE || _value[pin] > value + INPUT_74HC4051_TOLERANCE) { + _value[pin] = value; + (*_callbackFunction)(_analog,pin,value); + } + } +} + +int INPUT_74HC4051::getSpecificValue(uint8_t pin) { + if (pin >= 8) + return -1; + uint8_t r0,r1,r2; + r0 = bitRead(pin,0); + r1 = bitRead(pin,1); + r2 = bitRead(pin,2); + digitalWrite(_s0, r0); + digitalWrite(_s1, r1); + digitalWrite(_s2, r2); + //delayMicroseconds(10); + int value = analogRead(_analog); + _value[pin] = value; + return value; +} + diff --git a/source/libraries/INPUT_74HC4051/INPUT_74HC4051.h b/source/libraries/INPUT_74HC4051/INPUT_74HC4051.h new file mode 100644 index 0000000..c4523fa --- /dev/null +++ b/source/libraries/INPUT_74HC4051/INPUT_74HC4051.h @@ -0,0 +1,29 @@ +/* + INPUT_4051.h - Library for reading inputs from 4051 multiplexer +*/ +#ifndef INPUT_74HC4051_h +#define INPUT_74HC4051_h + +#define INPUT_74HC4051_TOLERANCE 1 + +#if !defined(CallbackFunction) +typedef void (*CallbackFunction)(int,int,int); +#endif + +class INPUT_74HC4051 +{ + public: + void begin(uint8_t analog, uint8_t s0, uint8_t s1, uint8_t s2,CallbackFunction cbF); + void loop(void); + int getSpecificValue(uint8_t pin); + private: + uint8_t _analog; + uint8_t _s0; + uint8_t _s1; + uint8_t _s2; + int _value[8]; + CallbackFunction _callbackFunction; +}; + + +#endif diff --git a/source/libraries/INPUT_MCP23017/INPUT_MCP23017.cpp b/source/libraries/INPUT_MCP23017/INPUT_MCP23017.cpp new file mode 100644 index 0000000..23fc90b --- /dev/null +++ b/source/libraries/INPUT_MCP23017/INPUT_MCP23017.cpp @@ -0,0 +1,115 @@ +#include + +#include "Arduino.h" +#include "INPUT_MCP23017.h" + +void INPUT_MCP23017::begin(uint8_t addr,CallbackFunction cbF) { + Wire.begin(); + + if (addr > 7) + _addr = 7; + else _addr = addr; + + _callbackFunction = cbF; + + // set defaults! + Wire.beginTransmission(MCP23017_ADDRESS | _addr); + Wire.write((byte)MCP23017_IODIRA); + Wire.write(0xFF); // all inputs on port A + Wire.endTransmission(); + + Wire.beginTransmission(MCP23017_ADDRESS | _addr); + Wire.write(MCP23017_IODIRB); + Wire.write(0xFF); // all inputs on port B + Wire.endTransmission(); + + + Wire.beginTransmission(MCP23017_ADDRESS | _addr); + Wire.write(MCP23017_GPPUA); + Wire.write(0xFF); // all pullup resistors on port A + Wire.endTransmission(); + + Wire.beginTransmission(MCP23017_ADDRESS | _addr); + Wire.write(MCP23017_GPPUB); + Wire.write(0xFF); // all pullup resistors on port B + Wire.endTransmission(); + + Wire.beginTransmission(MCP23017_ADDRESS | _addr); + Wire.write((byte)MCP23017_IPOLA); + Wire.write(0xFF); // inverse all inputs + Wire.endTransmission(); + + Wire.beginTransmission(MCP23017_ADDRESS | _addr); + Wire.write(MCP23017_IPOLB); + Wire.write(0xFF); // inverse all inputs + Wire.endTransmission(); + + //init start values + uint8_t pin,bank; + //read bank A + Wire.beginTransmission(MCP23017_ADDRESS | _addr); + Wire.write(MCP23017_GPIOA); + Wire.endTransmission(); + Wire.requestFrom(MCP23017_ADDRESS | _addr, 1); + bank = Wire.read(); + for (pin=0; pin<8; pin++) + _value[pin] = (bank >> pin) & 0x1; + //read bank B + Wire.beginTransmission(MCP23017_ADDRESS | _addr); + Wire.write(MCP23017_GPIOB); + Wire.endTransmission(); + Wire.requestFrom(MCP23017_ADDRESS | _addr, 1); + bank = Wire.read(); + for (pin=8; pin<16; pin++) + _value[pin] = (bank >> (pin-8)) & 0x1; +} + +void INPUT_MCP23017::loop() { + uint8_t pin,bank; + int value; + //read bank A + Wire.beginTransmission(MCP23017_ADDRESS | _addr); + Wire.write(MCP23017_GPIOA); + Wire.endTransmission(); + Wire.requestFrom(MCP23017_ADDRESS | _addr, 1); + bank = Wire.read(); + for (pin=0; pin<8; pin++) { + value = (bank >> pin) & 0x1; + if (_value[pin] != value) { + _value[pin] = value; + (*_callbackFunction)(_addr,pin,value); + } + } + //read bank B + Wire.beginTransmission(MCP23017_ADDRESS | _addr); + Wire.write(MCP23017_GPIOB); + Wire.endTransmission(); + Wire.requestFrom(MCP23017_ADDRESS | _addr, 1); + bank = Wire.read(); + for (pin=8; pin<16; pin++) { + value = (bank >> (pin-8)) & 0x1; + if (_value[pin] != value) { + _value[pin] = value; + (*_callbackFunction)(_addr,pin,value); + } + } +} + +int INPUT_MCP23017::getSpecificValue(uint8_t pin) { + if (pin > 16) + return LOW; + Wire.beginTransmission(MCP23017_ADDRESS | _addr); + uint8_t p = pin; + if (pin > 8) { + Wire.write(MCP23017_GPIOB); + p -= 8; + } else + Wire.write(MCP23017_GPIOA); + Wire.endTransmission(); + uint8_t bank = Wire.read(); + int value = (bank >> p) & 0x1; + _value[pin] = value; + return value; +} + + diff --git a/source/libraries/INPUT_MCP23017/INPUT_MCP23017.h b/source/libraries/INPUT_MCP23017/INPUT_MCP23017.h new file mode 100644 index 0000000..caf10d8 --- /dev/null +++ b/source/libraries/INPUT_MCP23017/INPUT_MCP23017.h @@ -0,0 +1,51 @@ +/* + INPUT_MCP23017.h - Library for reading inputs from MCP23017 port Expander +*/ +#ifndef INPUT_MCP23017_h +#define INPUT_MCP23017_h + +#if !defined(CallbackFunction) +typedef void (*CallbackFunction)(int,int,int); +#endif + +class INPUT_MCP23017 +{ + public: + void begin(uint8_t addr,CallbackFunction cbF); + void loop(void); + int getSpecificValue(uint8_t pin); + private: + uint8_t _addr; + int _value[16]; + CallbackFunction _callbackFunction; +}; + +#define MCP23017_ADDRESS 0x20 + +// registers (from https://github.com/adafruit/Adafruit-MCP23017-Arduino-Library/blob/master/Adafruit_MCP23017.h) +#define MCP23017_IODIRA 0x00 +#define MCP23017_IPOLA 0x02 +#define MCP23017_GPINTENA 0x04 +#define MCP23017_DEFVALA 0x06 +#define MCP23017_INTCONA 0x08 +#define MCP23017_IOCONA 0x0A +#define MCP23017_GPPUA 0x0C +#define MCP23017_INTFA 0x0E +#define MCP23017_INTCAPA 0x10 +#define MCP23017_GPIOA 0x12 +#define MCP23017_OLATA 0x14 + +#define MCP23017_IODIRB 0x01 +#define MCP23017_IPOLB 0x03 +#define MCP23017_GPINTENB 0x05 +#define MCP23017_DEFVALB 0x07 +#define MCP23017_INTCONB 0x09 +#define MCP23017_IOCONB 0x0B +#define MCP23017_GPPUB 0x0D +#define MCP23017_INTFB 0x0F +#define MCP23017_INTCAPB 0x11 +#define MCP23017_GPIOB 0x13 +#define MCP23017_OLATB 0x15 + + +#endif diff --git a/source/library/input_4051/input_4051.cpp b/source/library/input_4051/input_4051.cpp deleted file mode 100644 index 2e294c4..0000000 --- a/source/library/input_4051/input_4051.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - Morse.cpp - Library for flashing Morse code. - Created by David A. Mellis, November 2, 2007. - Released into the public domain. -*/ - -#include "Arduino.h" -#include "input_4051.h" - -const int tolerance = 4; - -input_4051::input_4051(int analogPin, int s0Pin, int s1Pin, int s2Pin, void (*valueChangeCallback(int,int))) -{ - _analog = analogPin; - _s0 = s0Pin; - _s1 = s1Pin; - _s2 = s2Pin; - pinMode(_analog,INPUT); - pinMode(_s0,OUTPUT); - pinMode(_s1,OUTPUT); - pinMode(_s2,OUTPUT); - _valueChangeCallback = valueChangeCallback; - _value = {-1,-1,-1,-1,-1,-1,-1,-1}; -} - -void input_4051::loop() -{ - for (count=0; count<=7; count++) { - r0 = bitRead(count,0); - r1 = bitRead(count,1); - r2 = bitRead(count,2); - digitalWrite(_s0, r0); - digitalWrite(_s1, r1); - digitalWrite(_s2, r2); - int read = analogRead(_analog); - if (value[count] < read - tolerance || value[count] > read + tolerance) { - value[count] = read; - _valueChangeCallback(count, read); - } - } -} - diff --git a/source/library/input_4051/input_4061.h b/source/library/input_4051/input_4061.h deleted file mode 100644 index 9e8c55d..0000000 --- a/source/library/input_4051/input_4061.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - input_4051.h - Library for reading inputs from 4051 multiplexer - Created by David A. Mellis, November 2, 2007. - Released into the public domain. -*/ -#ifndef input_4051_h -#define input_4051_h - -#include "Arduino.h" - - -class input_4051 -{ - public: - Morse(int analogPin, int s0Pin, int s1Pin, int s2Pin, void (*valueChangeCallback(int,int))); - void loop(void); - int getSpecificValue(int pin); - private: - int _analog; - int _s0; - int _s1; - int _s2; - void (*_valueChangeCallback(int,int); - int _value[8]; -}; - - -#endif diff --git a/source/sketches/testing/MIDI-Out_MCP23017.ino b/source/midi_in_out/midi_in_out.ino similarity index 100% rename from source/sketches/testing/MIDI-Out_MCP23017.ino rename to source/midi_in_out/midi_in_out.ino diff --git a/source/midi_in_out_softwareserial/midi_in_out_softwareserial.ino b/source/midi_in_out_softwareserial/midi_in_out_softwareserial.ino new file mode 100644 index 0000000..8afa539 --- /dev/null +++ b/source/midi_in_out_softwareserial/midi_in_out_softwareserial.ino @@ -0,0 +1,62 @@ +#include +#include + +#define IOPOLA 0x02 +#define GPPUA 0x12 +#define BIT_IS_SET(i, bits) (1 << i & bits) + +SoftwareSerial MIDI(10,11); + +boolean button[8]; + +void setup() +{ + //printing baudrate + Serial.begin(9600); + MIDI.begin(31250); + Wire.begin(); + Wire.beginTransmission(0x20); + Wire.write(0x12); // set MCP23017 memory pointer to GPIOB address + Wire.write(0xFF); //PULLUP + Wire.endTransmission(); +} + +void loop() +{ + Wire.beginTransmission(0x20); + Wire.write(0x12); // set MCP23017 memory pointer to GPIOB address + Wire.endTransmission(); + Wire.requestFrom(0x20, 1); // request one byte of data from MCP20317 + int inputs = Wire.read(); + delayMicroseconds(10); + //check if button is pressed + + int i; + for(i=0;i<8;i++) { + if (BIT_IS_SET(i,inputs)) { + if(!button[i]) { + button[i] = true; + midiSignal(144,60+i,115); + } + } else { + if(button[i]) { + button[i] = false; + midiSignal(128,60+i,0); + } + } + } +} + +//send MIDI signal through softwareserial +void midiSignal(byte b1, byte b2, byte b3) { + Serial.print(b1); + Serial.print(" "); + Serial.print(b2); + Serial.print(" "); + Serial.print(b3); + Serial.print(" "); + Serial.println(); + MIDI.write(b1); + MIDI.write(b2); + MIDI.write(b2); +} diff --git a/source/midi_led/midi_led.ino b/source/midi_led/midi_led.ino new file mode 100644 index 0000000..0e455b2 --- /dev/null +++ b/source/midi_led/midi_led.ino @@ -0,0 +1,45 @@ +/* + MIDI note player + + This sketch shows how to use the serial transmit pin (pin 1) to send MIDI note data. + If this circuit is connected to a MIDI synth, it will play + the notes F#-0 (0x1E) to F#-5 (0x5A) in sequence. + + + The circuit: + * digital in 1 connected to MIDI jack pin 5 + * MIDI jack pin 2 connected to ground + * MIDI jack pin 4 connected to +5V through 220-ohm resistor + Attach a MIDI cable to the jack, then to a MIDI synth, and play music. + + created 13 Jun 2006 + modified 13 Aug 2012 + by Tom Igoe + + This example code is in the public domain. + + http://www.arduino.cc/en/Tutorial/Midi + + */ + +void setup() { + // Set MIDI baud rate: + Serial.begin(9600); + pinMode(2, INPUT); + digitalWrite(2, HIGH); + pinMode(3, OUTPUT); +} + +void loop() { + button(); +} + +void button() { + int sensorVal = digitalRead(2); + if (sensorVal == HIGH) { + digitalWrite(3, LOW); + } + else { + digitalWrite(3, HIGH); + } +} diff --git a/source/piezo_input/piezo_input.ino b/source/piezo_input/piezo_input.ino new file mode 100644 index 0000000..b047d32 --- /dev/null +++ b/source/piezo_input/piezo_input.ino @@ -0,0 +1,9 @@ +void setup() { + Serial.begin(9600); +} + +void loop() { + int val = analogRead(5); + Serial.println(val); + delay(100); // we have to make a delay to avoid overloading the serial port +} diff --git a/source/sketches/testing/midi_in_out_softwareserial.ino b/source/sketches/testing/midi_in_out_softwareserial.ino deleted file mode 100644 index c3f368f..0000000 --- a/source/sketches/testing/midi_in_out_softwareserial.ino +++ /dev/null @@ -1,92 +0,0 @@ -#include - -// RX, TX for MIDI out -SoftwareSerial MIDI(10, 11); - -//button pin -const int switchPin = 6; -//rotary encoder pins -const int encAPin = 4; -const int encBPin = 5; - -//for sending note-off once after button is released -boolean btnOff = false; - -//old rotary encoder value -int encA = LOW; -//read rotary encoder value -int enc = HIGH; - -void setup() -{ - //printing baudrate - Serial.begin(9600); - //MIDI baudrate for software serial (pin 10 & 11) - MIDI.begin(31250); - //button and encoder pins as input - pinMode(switchPin, INPUT); - pinMode(encAPin, INPUT); - pinMode(encBPin, INPUT); - //activate pullup-resistors (read value is inverted, so LOW is active) - digitalWrite(switchPin, HIGH); - digitalWrite(encAPin, HIGH); - digitalWrite(encBPin, HIGH); -} - -void loop() -{ - //print incoming bytes on softwareserial, just for checking MIDI-in, worked - if (MIDI.available()) - Serial.println(MIDI.read()); - - //check if button is pressed - if (digitalRead(switchPin) == LOW) - { - if (!btnOff) { - //send note on - midiSignal(144,60,100); - btnOff = true; - } - } - if (digitalRead(switchPin) == HIGH) - { - //send note off - if (btnOff) { - midiSignal(128,60,0); - btnOff = false; - } - } - - //read encoder pin A - enc = digitalRead(encAPin); - //check if rotary encoder is turned - if ((encA == HIGH) && (enc == LOW)) { - //check direction of turning - if (digitalRead(encBPin) == HIGH) { - //send note on and note off directly, so signal is send on every turn - midiSignal(144,62,100); - midiSignal(128,62,100); - } else { - //other direction, other note value - midiSignal(144,61,100); - midiSignal(128,61,100); - } - } - //save "old" encoder value - encA = enc; -} - -//send MIDI signal through softwareserial -void midiSignal(byte b1, byte b2, byte b3) { - //debug printing - Serial.print("send: "); - Serial.print(b1); - Serial.print(" | "); - Serial.print(b2); - Serial.print(" | "); - Serial.print(b3); - Serial.println(""); - MIDI.write(b1); - MIDI.write(b2); - MIDI.write(b2); -}